Commit cc19b05e authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

Merge branches 'pm-devfreq' and 'pm-tools'

* pm-devfreq:
  PM / devfreq: remove redundant null pointer check before kfree
  PM / devfreq: stopping the governor before device_unregister()
  PM / devfreq: Convert to using %pOFn instead of device_node.name
  PM / devfreq: Make update_devfreq() public
  PM / devfreq: Don't adjust to user limits in governors
  PM / devfreq: Fix handling of min/max_freq == 0
  PM / devfreq: Drop custom MIN/MAX macros
  PM / devfreq: Fix devfreq_add_device() when drivers are built as modules.

* pm-tools:
  PM / tools: sleepgraph and bootgraph: upgrade to v5.2
  PM / tools: sleepgraph: first batch of v5.2 changes
  cpupower: Fix coredump on VMWare
  cpupower: Fix AMD Family 0x17 msr_pstate size
  cpupower: remove stringop-truncation waring
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/kmod.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/err.h> #include <linux/err.h>
...@@ -28,9 +29,6 @@ ...@@ -28,9 +29,6 @@
#include <linux/of.h> #include <linux/of.h>
#include "governor.h" #include "governor.h"
#define MAX(a,b) ((a > b) ? a : b)
#define MIN(a,b) ((a < b) ? a : b)
static struct class *devfreq_class; static struct class *devfreq_class;
/* /*
...@@ -221,6 +219,49 @@ static struct devfreq_governor *find_devfreq_governor(const char *name) ...@@ -221,6 +219,49 @@ static struct devfreq_governor *find_devfreq_governor(const char *name)
return ERR_PTR(-ENODEV); return ERR_PTR(-ENODEV);
} }
/**
* try_then_request_governor() - Try to find the governor and request the
* module if is not found.
* @name: name of the governor
*
* Search the list of devfreq governors and request the module and try again
* if is not found. This can happen when both drivers (the governor driver
* and the driver that call devfreq_add_device) are built as modules.
* devfreq_list_lock should be held by the caller. Returns the matched
* governor's pointer.
*/
static struct devfreq_governor *try_then_request_governor(const char *name)
{
struct devfreq_governor *governor;
int err = 0;
if (IS_ERR_OR_NULL(name)) {
pr_err("DEVFREQ: %s: Invalid parameters\n", __func__);
return ERR_PTR(-EINVAL);
}
WARN(!mutex_is_locked(&devfreq_list_lock),
"devfreq_list_lock must be locked.");
governor = find_devfreq_governor(name);
if (IS_ERR(governor)) {
mutex_unlock(&devfreq_list_lock);
if (!strncmp(name, DEVFREQ_GOV_SIMPLE_ONDEMAND,
DEVFREQ_NAME_LEN))
err = request_module("governor_%s", "simpleondemand");
else
err = request_module("governor_%s", name);
/* Restore previous state before return */
mutex_lock(&devfreq_list_lock);
if (err)
return NULL;
governor = find_devfreq_governor(name);
}
return governor;
}
static int devfreq_notify_transition(struct devfreq *devfreq, static int devfreq_notify_transition(struct devfreq *devfreq,
struct devfreq_freqs *freqs, unsigned int state) struct devfreq_freqs *freqs, unsigned int state)
{ {
...@@ -280,14 +321,14 @@ int update_devfreq(struct devfreq *devfreq) ...@@ -280,14 +321,14 @@ int update_devfreq(struct devfreq *devfreq)
* max_freq * max_freq
* min_freq * min_freq
*/ */
max_freq = MIN(devfreq->scaling_max_freq, devfreq->max_freq); max_freq = min(devfreq->scaling_max_freq, devfreq->max_freq);
min_freq = MAX(devfreq->scaling_min_freq, devfreq->min_freq); min_freq = max(devfreq->scaling_min_freq, devfreq->min_freq);
if (min_freq && freq < min_freq) { if (freq < min_freq) {
freq = min_freq; freq = min_freq;
flags &= ~DEVFREQ_FLAG_LEAST_UPPER_BOUND; /* Use GLB */ flags &= ~DEVFREQ_FLAG_LEAST_UPPER_BOUND; /* Use GLB */
} }
if (max_freq && freq > max_freq) { if (freq > max_freq) {
freq = max_freq; freq = max_freq;
flags |= DEVFREQ_FLAG_LEAST_UPPER_BOUND; /* Use LUB */ flags |= DEVFREQ_FLAG_LEAST_UPPER_BOUND; /* Use LUB */
} }
...@@ -534,10 +575,6 @@ static void devfreq_dev_release(struct device *dev) ...@@ -534,10 +575,6 @@ static void devfreq_dev_release(struct device *dev)
list_del(&devfreq->node); list_del(&devfreq->node);
mutex_unlock(&devfreq_list_lock); mutex_unlock(&devfreq_list_lock);
if (devfreq->governor)
devfreq->governor->event_handler(devfreq,
DEVFREQ_GOV_STOP, NULL);
if (devfreq->profile->exit) if (devfreq->profile->exit)
devfreq->profile->exit(devfreq->dev.parent); devfreq->profile->exit(devfreq->dev.parent);
...@@ -646,9 +683,8 @@ struct devfreq *devfreq_add_device(struct device *dev, ...@@ -646,9 +683,8 @@ struct devfreq *devfreq_add_device(struct device *dev,
mutex_unlock(&devfreq->lock); mutex_unlock(&devfreq->lock);
mutex_lock(&devfreq_list_lock); mutex_lock(&devfreq_list_lock);
list_add(&devfreq->node, &devfreq_list);
governor = find_devfreq_governor(devfreq->governor_name); governor = try_then_request_governor(devfreq->governor_name);
if (IS_ERR(governor)) { if (IS_ERR(governor)) {
dev_err(dev, "%s: Unable to find governor for the device\n", dev_err(dev, "%s: Unable to find governor for the device\n",
__func__); __func__);
...@@ -664,19 +700,20 @@ struct devfreq *devfreq_add_device(struct device *dev, ...@@ -664,19 +700,20 @@ struct devfreq *devfreq_add_device(struct device *dev,
__func__); __func__);
goto err_init; goto err_init;
} }
list_add(&devfreq->node, &devfreq_list);
mutex_unlock(&devfreq_list_lock); mutex_unlock(&devfreq_list_lock);
return devfreq; return devfreq;
err_init: err_init:
list_del(&devfreq->node);
mutex_unlock(&devfreq_list_lock); mutex_unlock(&devfreq_list_lock);
device_unregister(&devfreq->dev); devfreq_remove_device(devfreq);
devfreq = NULL; devfreq = NULL;
err_dev: err_dev:
if (devfreq) kfree(devfreq);
kfree(devfreq);
err_out: err_out:
return ERR_PTR(err); return ERR_PTR(err);
} }
...@@ -693,6 +730,9 @@ int devfreq_remove_device(struct devfreq *devfreq) ...@@ -693,6 +730,9 @@ int devfreq_remove_device(struct devfreq *devfreq)
if (!devfreq) if (!devfreq)
return -EINVAL; return -EINVAL;
if (devfreq->governor)
devfreq->governor->event_handler(devfreq,
DEVFREQ_GOV_STOP, NULL);
device_unregister(&devfreq->dev); device_unregister(&devfreq->dev);
return 0; return 0;
...@@ -991,7 +1031,7 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr, ...@@ -991,7 +1031,7 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr,
return -EINVAL; return -EINVAL;
mutex_lock(&devfreq_list_lock); mutex_lock(&devfreq_list_lock);
governor = find_devfreq_governor(str_governor); governor = try_then_request_governor(str_governor);
if (IS_ERR(governor)) { if (IS_ERR(governor)) {
ret = PTR_ERR(governor); ret = PTR_ERR(governor);
goto out; goto out;
...@@ -1126,17 +1166,26 @@ static ssize_t min_freq_store(struct device *dev, struct device_attribute *attr, ...@@ -1126,17 +1166,26 @@ static ssize_t min_freq_store(struct device *dev, struct device_attribute *attr,
struct devfreq *df = to_devfreq(dev); struct devfreq *df = to_devfreq(dev);
unsigned long value; unsigned long value;
int ret; int ret;
unsigned long max;
ret = sscanf(buf, "%lu", &value); ret = sscanf(buf, "%lu", &value);
if (ret != 1) if (ret != 1)
return -EINVAL; return -EINVAL;
mutex_lock(&df->lock); mutex_lock(&df->lock);
max = df->max_freq;
if (value && max && value > max) { if (value) {
ret = -EINVAL; if (value > df->max_freq) {
goto unlock; ret = -EINVAL;
goto unlock;
}
} else {
unsigned long *freq_table = df->profile->freq_table;
/* Get minimum frequency according to sorting order */
if (freq_table[0] < freq_table[df->profile->max_state - 1])
value = freq_table[0];
else
value = freq_table[df->profile->max_state - 1];
} }
df->min_freq = value; df->min_freq = value;
...@@ -1152,7 +1201,7 @@ static ssize_t min_freq_show(struct device *dev, struct device_attribute *attr, ...@@ -1152,7 +1201,7 @@ static ssize_t min_freq_show(struct device *dev, struct device_attribute *attr,
{ {
struct devfreq *df = to_devfreq(dev); struct devfreq *df = to_devfreq(dev);
return sprintf(buf, "%lu\n", MAX(df->scaling_min_freq, df->min_freq)); return sprintf(buf, "%lu\n", max(df->scaling_min_freq, df->min_freq));
} }
static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr, static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr,
...@@ -1161,17 +1210,26 @@ static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr, ...@@ -1161,17 +1210,26 @@ static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr,
struct devfreq *df = to_devfreq(dev); struct devfreq *df = to_devfreq(dev);
unsigned long value; unsigned long value;
int ret; int ret;
unsigned long min;
ret = sscanf(buf, "%lu", &value); ret = sscanf(buf, "%lu", &value);
if (ret != 1) if (ret != 1)
return -EINVAL; return -EINVAL;
mutex_lock(&df->lock); mutex_lock(&df->lock);
min = df->min_freq;
if (value && min && value < min) { if (value) {
ret = -EINVAL; if (value < df->min_freq) {
goto unlock; ret = -EINVAL;
goto unlock;
}
} else {
unsigned long *freq_table = df->profile->freq_table;
/* Get maximum frequency according to sorting order */
if (freq_table[0] < freq_table[df->profile->max_state - 1])
value = freq_table[df->profile->max_state - 1];
else
value = freq_table[0];
} }
df->max_freq = value; df->max_freq = value;
...@@ -1188,7 +1246,7 @@ static ssize_t max_freq_show(struct device *dev, struct device_attribute *attr, ...@@ -1188,7 +1246,7 @@ static ssize_t max_freq_show(struct device *dev, struct device_attribute *attr,
{ {
struct devfreq *df = to_devfreq(dev); struct devfreq *df = to_devfreq(dev);
return sprintf(buf, "%lu\n", MIN(df->scaling_max_freq, df->max_freq)); return sprintf(buf, "%lu\n", min(df->scaling_max_freq, df->max_freq));
} }
static DEVICE_ATTR_RW(max_freq); static DEVICE_ATTR_RW(max_freq);
......
...@@ -535,8 +535,8 @@ static int of_get_devfreq_events(struct device_node *np, ...@@ -535,8 +535,8 @@ static int of_get_devfreq_events(struct device_node *np,
if (i == ARRAY_SIZE(ppmu_events)) { if (i == ARRAY_SIZE(ppmu_events)) {
dev_warn(dev, dev_warn(dev,
"don't know how to configure events : %s\n", "don't know how to configure events : %pOFn\n",
node->name); node);
continue; continue;
} }
......
...@@ -25,6 +25,9 @@ ...@@ -25,6 +25,9 @@
#define DEVFREQ_GOV_SUSPEND 0x4 #define DEVFREQ_GOV_SUSPEND 0x4
#define DEVFREQ_GOV_RESUME 0x5 #define DEVFREQ_GOV_RESUME 0x5
#define DEVFREQ_MIN_FREQ 0
#define DEVFREQ_MAX_FREQ ULONG_MAX
/** /**
* struct devfreq_governor - Devfreq policy governor * struct devfreq_governor - Devfreq policy governor
* @node: list node - contains registered devfreq governors * @node: list node - contains registered devfreq governors
...@@ -54,9 +57,6 @@ struct devfreq_governor { ...@@ -54,9 +57,6 @@ struct devfreq_governor {
unsigned int event, void *data); unsigned int event, void *data);
}; };
/* Caution: devfreq->lock must be locked before calling update_devfreq */
extern int update_devfreq(struct devfreq *devfreq);
extern void devfreq_monitor_start(struct devfreq *devfreq); extern void devfreq_monitor_start(struct devfreq *devfreq);
extern void devfreq_monitor_stop(struct devfreq *devfreq); extern void devfreq_monitor_stop(struct devfreq *devfreq);
extern void devfreq_monitor_suspend(struct devfreq *devfreq); extern void devfreq_monitor_suspend(struct devfreq *devfreq);
......
...@@ -20,10 +20,7 @@ static int devfreq_performance_func(struct devfreq *df, ...@@ -20,10 +20,7 @@ static int devfreq_performance_func(struct devfreq *df,
* target callback should be able to get floor value as * target callback should be able to get floor value as
* said in devfreq.h * said in devfreq.h
*/ */
if (!df->max_freq) *freq = DEVFREQ_MAX_FREQ;
*freq = UINT_MAX;
else
*freq = df->max_freq;
return 0; return 0;
} }
......
...@@ -20,7 +20,7 @@ static int devfreq_powersave_func(struct devfreq *df, ...@@ -20,7 +20,7 @@ static int devfreq_powersave_func(struct devfreq *df,
* target callback should be able to get ceiling value as * target callback should be able to get ceiling value as
* said in devfreq.h * said in devfreq.h
*/ */
*freq = df->min_freq; *freq = DEVFREQ_MIN_FREQ;
return 0; return 0;
} }
......
...@@ -27,7 +27,6 @@ static int devfreq_simple_ondemand_func(struct devfreq *df, ...@@ -27,7 +27,6 @@ static int devfreq_simple_ondemand_func(struct devfreq *df,
unsigned int dfso_upthreshold = DFSO_UPTHRESHOLD; unsigned int dfso_upthreshold = DFSO_UPTHRESHOLD;
unsigned int dfso_downdifferential = DFSO_DOWNDIFFERENCTIAL; unsigned int dfso_downdifferential = DFSO_DOWNDIFFERENCTIAL;
struct devfreq_simple_ondemand_data *data = df->data; struct devfreq_simple_ondemand_data *data = df->data;
unsigned long max = (df->max_freq) ? df->max_freq : UINT_MAX;
err = devfreq_update_stats(df); err = devfreq_update_stats(df);
if (err) if (err)
...@@ -47,7 +46,7 @@ static int devfreq_simple_ondemand_func(struct devfreq *df, ...@@ -47,7 +46,7 @@ static int devfreq_simple_ondemand_func(struct devfreq *df,
/* Assume MAX if it is going to be divided by zero */ /* Assume MAX if it is going to be divided by zero */
if (stat->total_time == 0) { if (stat->total_time == 0) {
*freq = max; *freq = DEVFREQ_MAX_FREQ;
return 0; return 0;
} }
...@@ -60,13 +59,13 @@ static int devfreq_simple_ondemand_func(struct devfreq *df, ...@@ -60,13 +59,13 @@ static int devfreq_simple_ondemand_func(struct devfreq *df,
/* Set MAX if it's busy enough */ /* Set MAX if it's busy enough */
if (stat->busy_time * 100 > if (stat->busy_time * 100 >
stat->total_time * dfso_upthreshold) { stat->total_time * dfso_upthreshold) {
*freq = max; *freq = DEVFREQ_MAX_FREQ;
return 0; return 0;
} }
/* Set MAX if we do not know the initial frequency */ /* Set MAX if we do not know the initial frequency */
if (stat->current_frequency == 0) { if (stat->current_frequency == 0) {
*freq = max; *freq = DEVFREQ_MAX_FREQ;
return 0; return 0;
} }
...@@ -85,11 +84,6 @@ static int devfreq_simple_ondemand_func(struct devfreq *df, ...@@ -85,11 +84,6 @@ static int devfreq_simple_ondemand_func(struct devfreq *df,
b = div_u64(b, (dfso_upthreshold - dfso_downdifferential / 2)); b = div_u64(b, (dfso_upthreshold - dfso_downdifferential / 2));
*freq = (unsigned long) b; *freq = (unsigned long) b;
if (df->min_freq && *freq < df->min_freq)
*freq = df->min_freq;
if (df->max_freq && *freq > df->max_freq)
*freq = df->max_freq;
return 0; return 0;
} }
......
...@@ -26,19 +26,11 @@ static int devfreq_userspace_func(struct devfreq *df, unsigned long *freq) ...@@ -26,19 +26,11 @@ static int devfreq_userspace_func(struct devfreq *df, unsigned long *freq)
{ {
struct userspace_data *data = df->data; struct userspace_data *data = df->data;
if (data->valid) { if (data->valid)
unsigned long adjusted_freq = data->user_frequency; *freq = data->user_frequency;
else
if (df->max_freq && adjusted_freq > df->max_freq)
adjusted_freq = df->max_freq;
if (df->min_freq && adjusted_freq < df->min_freq)
adjusted_freq = df->min_freq;
*freq = adjusted_freq;
} else {
*freq = df->previous_freq; /* No user freq specified yet */ *freq = df->previous_freq; /* No user freq specified yet */
}
return 0; return 0;
} }
......
...@@ -198,6 +198,14 @@ extern void devm_devfreq_remove_device(struct device *dev, ...@@ -198,6 +198,14 @@ extern void devm_devfreq_remove_device(struct device *dev,
extern int devfreq_suspend_device(struct devfreq *devfreq); extern int devfreq_suspend_device(struct devfreq *devfreq);
extern int devfreq_resume_device(struct devfreq *devfreq); extern int devfreq_resume_device(struct devfreq *devfreq);
/**
* update_devfreq() - Reevaluate the device and configure frequency
* @devfreq: the devfreq device
*
* Note: devfreq->lock must be held
*/
extern int update_devfreq(struct devfreq *devfreq);
/* Helper functions for devfreq user device driver with OPP. */ /* Helper functions for devfreq user device driver with OPP. */
extern struct dev_pm_opp *devfreq_recommended_opp(struct device *dev, extern struct dev_pm_opp *devfreq_recommended_opp(struct device *dev,
unsigned long *freq, u32 flags); unsigned long *freq, u32 flags);
......
...@@ -145,7 +145,7 @@ struct config *prepare_default_config() ...@@ -145,7 +145,7 @@ struct config *prepare_default_config()
config->cpu = 0; config->cpu = 0;
config->prio = SCHED_HIGH; config->prio = SCHED_HIGH;
config->verbose = 0; config->verbose = 0;
strncpy(config->governor, "ondemand", 8); strncpy(config->governor, "ondemand", sizeof(config->governor));
config->output = stdout; config->output = stdout;
......
...@@ -200,6 +200,8 @@ static int get_boost_mode(unsigned int cpu) ...@@ -200,6 +200,8 @@ static int get_boost_mode(unsigned int cpu)
printf(_(" Boost States: %d\n"), b_states); printf(_(" Boost States: %d\n"), b_states);
printf(_(" Total States: %d\n"), pstate_no); printf(_(" Total States: %d\n"), pstate_no);
for (i = 0; i < pstate_no; i++) { for (i = 0; i < pstate_no; i++) {
if (!pstates[i])
continue;
if (i < b_states) if (i < b_states)
printf(_(" Pstate-Pb%d: %luMHz (boost state)" printf(_(" Pstate-Pb%d: %luMHz (boost state)"
"\n"), i, pstates[i]); "\n"), i, pstates[i]);
......
...@@ -33,7 +33,7 @@ union msr_pstate { ...@@ -33,7 +33,7 @@ union msr_pstate {
unsigned vid:8; unsigned vid:8;
unsigned iddval:8; unsigned iddval:8;
unsigned idddiv:2; unsigned idddiv:2;
unsigned res1:30; unsigned res1:31;
unsigned en:1; unsigned en:1;
} fam17h_bits; } fam17h_bits;
unsigned long long val; unsigned long long val;
...@@ -119,6 +119,11 @@ int decode_pstates(unsigned int cpu, unsigned int cpu_family, ...@@ -119,6 +119,11 @@ int decode_pstates(unsigned int cpu, unsigned int cpu_family,
} }
if (read_msr(cpu, MSR_AMD_PSTATE + i, &pstate.val)) if (read_msr(cpu, MSR_AMD_PSTATE + i, &pstate.val))
return -1; return -1;
if ((cpu_family == 0x17) && (!pstate.fam17h_bits.en))
continue;
else if (!pstate.bits.en)
continue;
pstates[i] = get_cof(cpu_family, pstate); pstates[i] = get_cof(cpu_family, pstate);
} }
*no = i; *no = i;
......
...@@ -23,8 +23,8 @@ install : uninstall ...@@ -23,8 +23,8 @@ install : uninstall
install -m 644 config/suspend-x2-proc.cfg $(DESTDIR)$(PREFIX)/lib/pm-graph/config install -m 644 config/suspend-x2-proc.cfg $(DESTDIR)$(PREFIX)/lib/pm-graph/config
install -d $(DESTDIR)$(PREFIX)/bin install -d $(DESTDIR)$(PREFIX)/bin
ln -s $(DESTDIR)$(PREFIX)/lib/pm-graph/bootgraph.py $(DESTDIR)$(PREFIX)/bin/bootgraph ln -s ../lib/pm-graph/bootgraph.py $(DESTDIR)$(PREFIX)/bin/bootgraph
ln -s $(DESTDIR)$(PREFIX)/lib/pm-graph/sleepgraph.py $(DESTDIR)$(PREFIX)/bin/sleepgraph ln -s ../lib/pm-graph/sleepgraph.py $(DESTDIR)$(PREFIX)/bin/sleepgraph
install -d $(DESTDIR)$(PREFIX)/share/man/man8 install -d $(DESTDIR)$(PREFIX)/share/man/man8
install bootgraph.8 $(DESTDIR)$(PREFIX)/share/man/man8 install bootgraph.8 $(DESTDIR)$(PREFIX)/share/man/man8
......
...@@ -34,6 +34,10 @@ from datetime import datetime, timedelta ...@@ -34,6 +34,10 @@ from datetime import datetime, timedelta
from subprocess import call, Popen, PIPE from subprocess import call, Popen, PIPE
import sleepgraph as aslib import sleepgraph as aslib
def pprint(msg):
print(msg)
sys.stdout.flush()
# ----------------- CLASSES -------------------- # ----------------- CLASSES --------------------
# Class: SystemValues # Class: SystemValues
...@@ -157,11 +161,11 @@ class SystemValues(aslib.SystemValues): ...@@ -157,11 +161,11 @@ class SystemValues(aslib.SystemValues):
return cmdline return cmdline
def manualRebootRequired(self): def manualRebootRequired(self):
cmdline = self.kernelParams() cmdline = self.kernelParams()
print 'To generate a new timeline manually, follow these steps:\n' pprint('To generate a new timeline manually, follow these steps:\n\n'\
print '1. Add the CMDLINE string to your kernel command line.' '1. Add the CMDLINE string to your kernel command line.\n'\
print '2. Reboot the system.' '2. Reboot the system.\n'\
print '3. After reboot, re-run this tool with the same arguments but no command (w/o -reboot or -manual).\n' '3. After reboot, re-run this tool with the same arguments but no command (w/o -reboot or -manual).\n\n'\
print 'CMDLINE="%s"' % cmdline 'CMDLINE="%s"' % cmdline)
sys.exit() sys.exit()
def blGrub(self): def blGrub(self):
blcmd = '' blcmd = ''
...@@ -431,7 +435,7 @@ def parseTraceLog(data): ...@@ -431,7 +435,7 @@ def parseTraceLog(data):
if len(cg.list) < 1 or cg.invalid or (cg.end - cg.start == 0): if len(cg.list) < 1 or cg.invalid or (cg.end - cg.start == 0):
continue continue
if(not cg.postProcess()): if(not cg.postProcess()):
print('Sanity check failed for %s-%d' % (proc, pid)) pprint('Sanity check failed for %s-%d' % (proc, pid))
continue continue
# match cg data to devices # match cg data to devices
devname = data.deviceMatch(pid, cg) devname = data.deviceMatch(pid, cg)
...@@ -442,8 +446,8 @@ def parseTraceLog(data): ...@@ -442,8 +446,8 @@ def parseTraceLog(data):
sysvals.vprint('%s callgraph found for %s %s-%d [%f - %f]' %\ sysvals.vprint('%s callgraph found for %s %s-%d [%f - %f]' %\
(kind, cg.name, proc, pid, cg.start, cg.end)) (kind, cg.name, proc, pid, cg.start, cg.end))
elif len(cg.list) > 1000000: elif len(cg.list) > 1000000:
print 'WARNING: the callgraph found for %s is massive! (%d lines)' %\ pprint('WARNING: the callgraph found for %s is massive! (%d lines)' %\
(devname, len(cg.list)) (devname, len(cg.list)))
# Function: retrieveLogs # Function: retrieveLogs
# Description: # Description:
...@@ -528,7 +532,7 @@ def createBootGraph(data): ...@@ -528,7 +532,7 @@ def createBootGraph(data):
tMax = data.end tMax = data.end
tTotal = tMax - t0 tTotal = tMax - t0
if(tTotal == 0): if(tTotal == 0):
print('ERROR: No timeline data') pprint('ERROR: No timeline data')
return False return False
user_mode = '%.0f'%(data.tUserMode*1000) user_mode = '%.0f'%(data.tUserMode*1000)
last_init = '%.0f'%(tTotal*1000) last_init = '%.0f'%(tTotal*1000)
...@@ -734,7 +738,7 @@ def updateCron(restore=False): ...@@ -734,7 +738,7 @@ def updateCron(restore=False):
op.close() op.close()
res = call([cmd, cronfile]) res = call([cmd, cronfile])
except Exception, e: except Exception, e:
print 'Exception: %s' % str(e) pprint('Exception: %s' % str(e))
shutil.move(backfile, cronfile) shutil.move(backfile, cronfile)
res = -1 res = -1
if res != 0: if res != 0:
...@@ -750,7 +754,7 @@ def updateGrub(restore=False): ...@@ -750,7 +754,7 @@ def updateGrub(restore=False):
call(sysvals.blexec, stderr=PIPE, stdout=PIPE, call(sysvals.blexec, stderr=PIPE, stdout=PIPE,
env={'PATH': '.:/sbin:/usr/sbin:/usr/bin:/sbin:/bin'}) env={'PATH': '.:/sbin:/usr/sbin:/usr/bin:/sbin:/bin'})
except Exception, e: except Exception, e:
print 'Exception: %s\n' % str(e) pprint('Exception: %s\n' % str(e))
return return
# extract the option and create a grub config without it # extract the option and create a grub config without it
sysvals.rootUser(True) sysvals.rootUser(True)
...@@ -797,7 +801,7 @@ def updateGrub(restore=False): ...@@ -797,7 +801,7 @@ def updateGrub(restore=False):
res = call(sysvals.blexec) res = call(sysvals.blexec)
os.remove(grubfile) os.remove(grubfile)
except Exception, e: except Exception, e:
print 'Exception: %s' % str(e) pprint('Exception: %s' % str(e))
res = -1 res = -1
# cleanup # cleanup
shutil.move(tempfile, grubfile) shutil.move(tempfile, grubfile)
...@@ -821,7 +825,7 @@ def updateKernelParams(restore=False): ...@@ -821,7 +825,7 @@ def updateKernelParams(restore=False):
def doError(msg, help=False): def doError(msg, help=False):
if help == True: if help == True:
printHelp() printHelp()
print 'ERROR: %s\n' % msg pprint('ERROR: %s\n' % msg)
sysvals.outputResult({'error':msg}) sysvals.outputResult({'error':msg})
sys.exit() sys.exit()
...@@ -829,52 +833,51 @@ def doError(msg, help=False): ...@@ -829,52 +833,51 @@ def doError(msg, help=False):
# Description: # Description:
# print out the help text # print out the help text
def printHelp(): def printHelp():
print('') pprint('\n%s v%s\n'\
print('%s v%s' % (sysvals.title, sysvals.version)) 'Usage: bootgraph <options> <command>\n'\
print('Usage: bootgraph <options> <command>') '\n'\
print('') 'Description:\n'\
print('Description:') ' This tool reads in a dmesg log of linux kernel boot and\n'\
print(' This tool reads in a dmesg log of linux kernel boot and') ' creates an html representation of the boot timeline up to\n'\
print(' creates an html representation of the boot timeline up to') ' the start of the init process.\n'\
print(' the start of the init process.') '\n'\
print('') ' If no specific command is given the tool reads the current dmesg\n'\
print(' If no specific command is given the tool reads the current dmesg') ' and/or ftrace log and creates a timeline\n'\
print(' and/or ftrace log and creates a timeline') '\n'\
print('') ' Generates output files in subdirectory: boot-yymmdd-HHMMSS\n'\
print(' Generates output files in subdirectory: boot-yymmdd-HHMMSS') ' HTML output: <hostname>_boot.html\n'\
print(' HTML output: <hostname>_boot.html') ' raw dmesg output: <hostname>_boot_dmesg.txt\n'\
print(' raw dmesg output: <hostname>_boot_dmesg.txt') ' raw ftrace output: <hostname>_boot_ftrace.txt\n'\
print(' raw ftrace output: <hostname>_boot_ftrace.txt') '\n'\
print('') 'Options:\n'\
print('Options:') ' -h Print this help text\n'\
print(' -h Print this help text') ' -v Print the current tool version\n'\
print(' -v Print the current tool version') ' -verbose Print extra information during execution and analysis\n'\
print(' -verbose Print extra information during execution and analysis') ' -addlogs Add the dmesg log to the html output\n'\
print(' -addlogs Add the dmesg log to the html output') ' -result fn Export a results table to a text file for parsing.\n'\
print(' -result fn Export a results table to a text file for parsing.') ' -o name Overrides the output subdirectory name when running a new test\n'\
print(' -o name Overrides the output subdirectory name when running a new test') ' default: boot-{date}-{time}\n'\
print(' default: boot-{date}-{time}') ' [advanced]\n'\
print(' [advanced]') ' -fstat Use ftrace to add function detail and statistics (default: disabled)\n'\
print(' -fstat Use ftrace to add function detail and statistics (default: disabled)') ' -f/-callgraph Add callgraph detail, can be very large (default: disabled)\n'\
print(' -f/-callgraph Add callgraph detail, can be very large (default: disabled)') ' -maxdepth N limit the callgraph data to N call levels (default: 2)\n'\
print(' -maxdepth N limit the callgraph data to N call levels (default: 2)') ' -mincg ms Discard all callgraphs shorter than ms milliseconds (e.g. 0.001 for us)\n'\
print(' -mincg ms Discard all callgraphs shorter than ms milliseconds (e.g. 0.001 for us)') ' -timeprec N Number of significant digits in timestamps (0:S, 3:ms, [6:us])\n'\
print(' -timeprec N Number of significant digits in timestamps (0:S, 3:ms, [6:us])') ' -expandcg pre-expand the callgraph data in the html output (default: disabled)\n'\
print(' -expandcg pre-expand the callgraph data in the html output (default: disabled)') ' -func list Limit ftrace to comma-delimited list of functions (default: do_one_initcall)\n'\
print(' -func list Limit ftrace to comma-delimited list of functions (default: do_one_initcall)') ' -cgfilter S Filter the callgraph output in the timeline\n'\
print(' -cgfilter S Filter the callgraph output in the timeline') ' -cgskip file Callgraph functions to skip, off to disable (default: cgskip.txt)\n'\
print(' -cgskip file Callgraph functions to skip, off to disable (default: cgskip.txt)') ' -bl name Use the following boot loader for kernel params (default: grub)\n'\
print(' -bl name Use the following boot loader for kernel params (default: grub)') ' -reboot Reboot the machine automatically and generate a new timeline\n'\
print(' -reboot Reboot the machine automatically and generate a new timeline') ' -manual Show the steps to generate a new timeline manually (used with -reboot)\n'\
print(' -manual Show the steps to generate a new timeline manually (used with -reboot)') '\n'\
print('') 'Other commands:\n'\
print('Other commands:') ' -flistall Print all functions capable of being captured in ftrace\n'\
print(' -flistall Print all functions capable of being captured in ftrace') ' -sysinfo Print out system info extracted from BIOS\n'\
print(' -sysinfo Print out system info extracted from BIOS') ' [redo]\n'\
print(' [redo]') ' -dmesg file Create HTML output using dmesg input (used with -ftrace)\n'\
print(' -dmesg file Create HTML output using dmesg input (used with -ftrace)') ' -ftrace file Create HTML output using ftrace input (used with -dmesg)\n'\
print(' -ftrace file Create HTML output using ftrace input (used with -dmesg)') '' % (sysvals.title, sysvals.version))
print('')
return True return True
# ----------------- MAIN -------------------- # ----------------- MAIN --------------------
...@@ -895,7 +898,7 @@ if __name__ == '__main__': ...@@ -895,7 +898,7 @@ if __name__ == '__main__':
printHelp() printHelp()
sys.exit() sys.exit()
elif(arg == '-v'): elif(arg == '-v'):
print("Version %s" % sysvals.version) pprint("Version %s" % sysvals.version)
sys.exit() sys.exit()
elif(arg == '-verbose'): elif(arg == '-verbose'):
sysvals.verbose = True sysvals.verbose = True
...@@ -1016,7 +1019,7 @@ if __name__ == '__main__': ...@@ -1016,7 +1019,7 @@ if __name__ == '__main__':
print f print f
elif cmd == 'checkbl': elif cmd == 'checkbl':
sysvals.getBootLoader() sysvals.getBootLoader()
print 'Boot Loader: %s\n%s' % (sysvals.bootloader, sysvals.blexec) pprint('Boot Loader: %s\n%s' % (sysvals.bootloader, sysvals.blexec))
elif(cmd == 'sysinfo'): elif(cmd == 'sysinfo'):
sysvals.printSystemInfo(True) sysvals.printSystemInfo(True)
sys.exit() sys.exit()
......
...@@ -27,6 +27,7 @@ ktime_get ...@@ -27,6 +27,7 @@ ktime_get
# console calls # console calls
printk printk
dev_printk dev_printk
__dev_printk
console_unlock console_unlock
# memory handling # memory handling
......
...@@ -105,7 +105,7 @@ override-dev-timeline-functions: true ...@@ -105,7 +105,7 @@ override-dev-timeline-functions: true
# example: [color=#CC00CC] # example: [color=#CC00CC]
# #
# arglist: A list of arguments from registers/stack addresses. See URL: # arglist: A list of arguments from registers/stack addresses. See URL:
# https://www.kernel.org/doc/Documentation/trace/kprobetrace.rst # https://www.kernel.org/doc/Documentation/trace/kprobetrace.txt
# #
# example: cpu=%di:s32 # example: cpu=%di:s32
# #
...@@ -170,7 +170,7 @@ pm_restore_console: ...@@ -170,7 +170,7 @@ pm_restore_console:
# example: [color=#CC00CC] # example: [color=#CC00CC]
# #
# arglist: A list of arguments from registers/stack addresses. See URL: # arglist: A list of arguments from registers/stack addresses. See URL:
# https://www.kernel.org/doc/Documentation/trace/kprobetrace.rst # https://www.kernel.org/doc/Documentation/trace/kprobetrace.txt
# #
# example: port=+36(%di):s32 # example: port=+36(%di):s32
# #
......
...@@ -65,9 +65,9 @@ During test, enable/disable runtime suspend for all devices. The test is delayed ...@@ -65,9 +65,9 @@ During test, enable/disable runtime suspend for all devices. The test is delayed
by 5 seconds to allow runtime suspend changes to occur. The settings are restored by 5 seconds to allow runtime suspend changes to occur. The settings are restored
after the test is complete. after the test is complete.
.TP .TP
\fB-display \fIon/off\fR \fB-display \fIon/off/standby/suspend\fR
Turn the display on or off for the test using the xset command. This helps Switch the display to the requested mode for the test using the xset command.
maintain the consistecy of test data for better comparison. This helps maintain the consistency of test data for better comparison.
.TP .TP
\fB-skiphtml\fR \fB-skiphtml\fR
Run the test and capture the trace logs, but skip the timeline generation. Run the test and capture the trace logs, but skip the timeline generation.
...@@ -183,6 +183,13 @@ Print out the contents of the ACPI Firmware Performance Data Table. ...@@ -183,6 +183,13 @@ Print out the contents of the ACPI Firmware Performance Data Table.
\fB-battery\fR \fB-battery\fR
Print out battery status and current charge. Print out battery status and current charge.
.TP .TP
\fB-xon/-xoff/-xstandby/-xsuspend\fR
Test xset by attempting to switch the display to the given mode. This
is the same command which will be issued by \fB-display \fImode\fR.
.TP
\fB-xstat\fR
Get the current DPMS display mode.
.TP
\fB-sysinfo\fR \fB-sysinfo\fR
Print out system info extracted from BIOS. Reads /dev/mem directly instead of going through dmidecode. Print out system info extracted from BIOS. Reads /dev/mem directly instead of going through dmidecode.
.TP .TP
......
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment