mirror of https://gitee.com/openkylin/linux.git
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
This commit is contained in:
commit
cc19b05e38
|
@ -11,6 +11,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/kmod.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/err.h>
|
||||
|
@ -28,9 +29,6 @@
|
|||
#include <linux/of.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;
|
||||
|
||||
/*
|
||||
|
@ -221,6 +219,49 @@ static struct devfreq_governor *find_devfreq_governor(const char *name)
|
|||
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,
|
||||
struct devfreq_freqs *freqs, unsigned int state)
|
||||
{
|
||||
|
@ -280,14 +321,14 @@ int update_devfreq(struct devfreq *devfreq)
|
|||
* max_freq
|
||||
* min_freq
|
||||
*/
|
||||
max_freq = MIN(devfreq->scaling_max_freq, devfreq->max_freq);
|
||||
min_freq = MAX(devfreq->scaling_min_freq, devfreq->min_freq);
|
||||
max_freq = min(devfreq->scaling_max_freq, devfreq->max_freq);
|
||||
min_freq = max(devfreq->scaling_min_freq, devfreq->min_freq);
|
||||
|
||||
if (min_freq && freq < min_freq) {
|
||||
if (freq < min_freq) {
|
||||
freq = min_freq;
|
||||
flags &= ~DEVFREQ_FLAG_LEAST_UPPER_BOUND; /* Use GLB */
|
||||
}
|
||||
if (max_freq && freq > max_freq) {
|
||||
if (freq > max_freq) {
|
||||
freq = max_freq;
|
||||
flags |= DEVFREQ_FLAG_LEAST_UPPER_BOUND; /* Use LUB */
|
||||
}
|
||||
|
@ -534,10 +575,6 @@ static void devfreq_dev_release(struct device *dev)
|
|||
list_del(&devfreq->node);
|
||||
mutex_unlock(&devfreq_list_lock);
|
||||
|
||||
if (devfreq->governor)
|
||||
devfreq->governor->event_handler(devfreq,
|
||||
DEVFREQ_GOV_STOP, NULL);
|
||||
|
||||
if (devfreq->profile->exit)
|
||||
devfreq->profile->exit(devfreq->dev.parent);
|
||||
|
||||
|
@ -646,9 +683,8 @@ struct devfreq *devfreq_add_device(struct device *dev,
|
|||
mutex_unlock(&devfreq->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)) {
|
||||
dev_err(dev, "%s: Unable to find governor for the device\n",
|
||||
__func__);
|
||||
|
@ -664,19 +700,20 @@ struct devfreq *devfreq_add_device(struct device *dev,
|
|||
__func__);
|
||||
goto err_init;
|
||||
}
|
||||
|
||||
list_add(&devfreq->node, &devfreq_list);
|
||||
|
||||
mutex_unlock(&devfreq_list_lock);
|
||||
|
||||
return devfreq;
|
||||
|
||||
err_init:
|
||||
list_del(&devfreq->node);
|
||||
mutex_unlock(&devfreq_list_lock);
|
||||
|
||||
device_unregister(&devfreq->dev);
|
||||
devfreq_remove_device(devfreq);
|
||||
devfreq = NULL;
|
||||
err_dev:
|
||||
if (devfreq)
|
||||
kfree(devfreq);
|
||||
kfree(devfreq);
|
||||
err_out:
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
@ -693,6 +730,9 @@ int devfreq_remove_device(struct devfreq *devfreq)
|
|||
if (!devfreq)
|
||||
return -EINVAL;
|
||||
|
||||
if (devfreq->governor)
|
||||
devfreq->governor->event_handler(devfreq,
|
||||
DEVFREQ_GOV_STOP, NULL);
|
||||
device_unregister(&devfreq->dev);
|
||||
|
||||
return 0;
|
||||
|
@ -991,7 +1031,7 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr,
|
|||
return -EINVAL;
|
||||
|
||||
mutex_lock(&devfreq_list_lock);
|
||||
governor = find_devfreq_governor(str_governor);
|
||||
governor = try_then_request_governor(str_governor);
|
||||
if (IS_ERR(governor)) {
|
||||
ret = PTR_ERR(governor);
|
||||
goto out;
|
||||
|
@ -1126,17 +1166,26 @@ static ssize_t min_freq_store(struct device *dev, struct device_attribute *attr,
|
|||
struct devfreq *df = to_devfreq(dev);
|
||||
unsigned long value;
|
||||
int ret;
|
||||
unsigned long max;
|
||||
|
||||
ret = sscanf(buf, "%lu", &value);
|
||||
if (ret != 1)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&df->lock);
|
||||
max = df->max_freq;
|
||||
if (value && max && value > max) {
|
||||
ret = -EINVAL;
|
||||
goto unlock;
|
||||
|
||||
if (value) {
|
||||
if (value > df->max_freq) {
|
||||
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;
|
||||
|
@ -1152,7 +1201,7 @@ static ssize_t min_freq_show(struct device *dev, struct device_attribute *attr,
|
|||
{
|
||||
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,
|
||||
|
@ -1161,17 +1210,26 @@ static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr,
|
|||
struct devfreq *df = to_devfreq(dev);
|
||||
unsigned long value;
|
||||
int ret;
|
||||
unsigned long min;
|
||||
|
||||
ret = sscanf(buf, "%lu", &value);
|
||||
if (ret != 1)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&df->lock);
|
||||
min = df->min_freq;
|
||||
if (value && min && value < min) {
|
||||
ret = -EINVAL;
|
||||
goto unlock;
|
||||
|
||||
if (value) {
|
||||
if (value < df->min_freq) {
|
||||
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;
|
||||
|
@ -1188,7 +1246,7 @@ static ssize_t max_freq_show(struct device *dev, struct device_attribute *attr,
|
|||
{
|
||||
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);
|
||||
|
||||
|
|
|
@ -535,8 +535,8 @@ static int of_get_devfreq_events(struct device_node *np,
|
|||
|
||||
if (i == ARRAY_SIZE(ppmu_events)) {
|
||||
dev_warn(dev,
|
||||
"don't know how to configure events : %s\n",
|
||||
node->name);
|
||||
"don't know how to configure events : %pOFn\n",
|
||||
node);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
#define DEVFREQ_GOV_SUSPEND 0x4
|
||||
#define DEVFREQ_GOV_RESUME 0x5
|
||||
|
||||
#define DEVFREQ_MIN_FREQ 0
|
||||
#define DEVFREQ_MAX_FREQ ULONG_MAX
|
||||
|
||||
/**
|
||||
* struct devfreq_governor - Devfreq policy governor
|
||||
* @node: list node - contains registered devfreq governors
|
||||
|
@ -54,9 +57,6 @@ struct devfreq_governor {
|
|||
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_stop(struct devfreq *devfreq);
|
||||
extern void devfreq_monitor_suspend(struct devfreq *devfreq);
|
||||
|
|
|
@ -20,10 +20,7 @@ static int devfreq_performance_func(struct devfreq *df,
|
|||
* target callback should be able to get floor value as
|
||||
* said in devfreq.h
|
||||
*/
|
||||
if (!df->max_freq)
|
||||
*freq = UINT_MAX;
|
||||
else
|
||||
*freq = df->max_freq;
|
||||
*freq = DEVFREQ_MAX_FREQ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ static int devfreq_powersave_func(struct devfreq *df,
|
|||
* target callback should be able to get ceiling value as
|
||||
* said in devfreq.h
|
||||
*/
|
||||
*freq = df->min_freq;
|
||||
*freq = DEVFREQ_MIN_FREQ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,6 @@ static int devfreq_simple_ondemand_func(struct devfreq *df,
|
|||
unsigned int dfso_upthreshold = DFSO_UPTHRESHOLD;
|
||||
unsigned int dfso_downdifferential = DFSO_DOWNDIFFERENCTIAL;
|
||||
struct devfreq_simple_ondemand_data *data = df->data;
|
||||
unsigned long max = (df->max_freq) ? df->max_freq : UINT_MAX;
|
||||
|
||||
err = devfreq_update_stats(df);
|
||||
if (err)
|
||||
|
@ -47,7 +46,7 @@ static int devfreq_simple_ondemand_func(struct devfreq *df,
|
|||
|
||||
/* Assume MAX if it is going to be divided by zero */
|
||||
if (stat->total_time == 0) {
|
||||
*freq = max;
|
||||
*freq = DEVFREQ_MAX_FREQ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -60,13 +59,13 @@ static int devfreq_simple_ondemand_func(struct devfreq *df,
|
|||
/* Set MAX if it's busy enough */
|
||||
if (stat->busy_time * 100 >
|
||||
stat->total_time * dfso_upthreshold) {
|
||||
*freq = max;
|
||||
*freq = DEVFREQ_MAX_FREQ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set MAX if we do not know the initial frequency */
|
||||
if (stat->current_frequency == 0) {
|
||||
*freq = max;
|
||||
*freq = DEVFREQ_MAX_FREQ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -85,11 +84,6 @@ static int devfreq_simple_ondemand_func(struct devfreq *df,
|
|||
b = div_u64(b, (dfso_upthreshold - dfso_downdifferential / 2));
|
||||
*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;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,19 +26,11 @@ static int devfreq_userspace_func(struct devfreq *df, unsigned long *freq)
|
|||
{
|
||||
struct userspace_data *data = df->data;
|
||||
|
||||
if (data->valid) {
|
||||
unsigned long adjusted_freq = data->user_frequency;
|
||||
|
||||
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 {
|
||||
if (data->valid)
|
||||
*freq = data->user_frequency;
|
||||
else
|
||||
*freq = df->previous_freq; /* No user freq specified yet */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -198,6 +198,14 @@ extern void devm_devfreq_remove_device(struct device *dev,
|
|||
extern int devfreq_suspend_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. */
|
||||
extern struct dev_pm_opp *devfreq_recommended_opp(struct device *dev,
|
||||
unsigned long *freq, u32 flags);
|
||||
|
|
|
@ -145,7 +145,7 @@ struct config *prepare_default_config()
|
|||
config->cpu = 0;
|
||||
config->prio = SCHED_HIGH;
|
||||
config->verbose = 0;
|
||||
strncpy(config->governor, "ondemand", 8);
|
||||
strncpy(config->governor, "ondemand", sizeof(config->governor));
|
||||
|
||||
config->output = stdout;
|
||||
|
||||
|
|
|
@ -200,6 +200,8 @@ static int get_boost_mode(unsigned int cpu)
|
|||
printf(_(" Boost States: %d\n"), b_states);
|
||||
printf(_(" Total States: %d\n"), pstate_no);
|
||||
for (i = 0; i < pstate_no; i++) {
|
||||
if (!pstates[i])
|
||||
continue;
|
||||
if (i < b_states)
|
||||
printf(_(" Pstate-Pb%d: %luMHz (boost state)"
|
||||
"\n"), i, pstates[i]);
|
||||
|
|
|
@ -33,7 +33,7 @@ union msr_pstate {
|
|||
unsigned vid:8;
|
||||
unsigned iddval:8;
|
||||
unsigned idddiv:2;
|
||||
unsigned res1:30;
|
||||
unsigned res1:31;
|
||||
unsigned en:1;
|
||||
} fam17h_bits;
|
||||
unsigned long long val;
|
||||
|
@ -119,6 +119,11 @@ int decode_pstates(unsigned int cpu, unsigned int cpu_family,
|
|||
}
|
||||
if (read_msr(cpu, MSR_AMD_PSTATE + i, &pstate.val))
|
||||
return -1;
|
||||
if ((cpu_family == 0x17) && (!pstate.fam17h_bits.en))
|
||||
continue;
|
||||
else if (!pstate.bits.en)
|
||||
continue;
|
||||
|
||||
pstates[i] = get_cof(cpu_family, pstate);
|
||||
}
|
||||
*no = i;
|
||||
|
|
|
@ -23,8 +23,8 @@ install : uninstall
|
|||
install -m 644 config/suspend-x2-proc.cfg $(DESTDIR)$(PREFIX)/lib/pm-graph/config
|
||||
|
||||
install -d $(DESTDIR)$(PREFIX)/bin
|
||||
ln -s $(DESTDIR)$(PREFIX)/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/bootgraph.py $(DESTDIR)$(PREFIX)/bin/bootgraph
|
||||
ln -s ../lib/pm-graph/sleepgraph.py $(DESTDIR)$(PREFIX)/bin/sleepgraph
|
||||
|
||||
install -d $(DESTDIR)$(PREFIX)/share/man/man8
|
||||
install bootgraph.8 $(DESTDIR)$(PREFIX)/share/man/man8
|
||||
|
|
|
@ -34,6 +34,10 @@ from datetime import datetime, timedelta
|
|||
from subprocess import call, Popen, PIPE
|
||||
import sleepgraph as aslib
|
||||
|
||||
def pprint(msg):
|
||||
print(msg)
|
||||
sys.stdout.flush()
|
||||
|
||||
# ----------------- CLASSES --------------------
|
||||
|
||||
# Class: SystemValues
|
||||
|
@ -157,11 +161,11 @@ class SystemValues(aslib.SystemValues):
|
|||
return cmdline
|
||||
def manualRebootRequired(self):
|
||||
cmdline = self.kernelParams()
|
||||
print 'To generate a new timeline manually, follow these steps:\n'
|
||||
print '1. Add the CMDLINE string to your kernel command line.'
|
||||
print '2. Reboot the system.'
|
||||
print '3. After reboot, re-run this tool with the same arguments but no command (w/o -reboot or -manual).\n'
|
||||
print 'CMDLINE="%s"' % cmdline
|
||||
pprint('To generate a new timeline manually, follow these steps:\n\n'\
|
||||
'1. Add the CMDLINE string to your kernel command line.\n'\
|
||||
'2. Reboot the system.\n'\
|
||||
'3. After reboot, re-run this tool with the same arguments but no command (w/o -reboot or -manual).\n\n'\
|
||||
'CMDLINE="%s"' % cmdline)
|
||||
sys.exit()
|
||||
def blGrub(self):
|
||||
blcmd = ''
|
||||
|
@ -431,7 +435,7 @@ def parseTraceLog(data):
|
|||
if len(cg.list) < 1 or cg.invalid or (cg.end - cg.start == 0):
|
||||
continue
|
||||
if(not cg.postProcess()):
|
||||
print('Sanity check failed for %s-%d' % (proc, pid))
|
||||
pprint('Sanity check failed for %s-%d' % (proc, pid))
|
||||
continue
|
||||
# match cg data to devices
|
||||
devname = data.deviceMatch(pid, cg)
|
||||
|
@ -442,8 +446,8 @@ def parseTraceLog(data):
|
|||
sysvals.vprint('%s callgraph found for %s %s-%d [%f - %f]' %\
|
||||
(kind, cg.name, proc, pid, cg.start, cg.end))
|
||||
elif len(cg.list) > 1000000:
|
||||
print 'WARNING: the callgraph found for %s is massive! (%d lines)' %\
|
||||
(devname, len(cg.list))
|
||||
pprint('WARNING: the callgraph found for %s is massive! (%d lines)' %\
|
||||
(devname, len(cg.list)))
|
||||
|
||||
# Function: retrieveLogs
|
||||
# Description:
|
||||
|
@ -528,7 +532,7 @@ def createBootGraph(data):
|
|||
tMax = data.end
|
||||
tTotal = tMax - t0
|
||||
if(tTotal == 0):
|
||||
print('ERROR: No timeline data')
|
||||
pprint('ERROR: No timeline data')
|
||||
return False
|
||||
user_mode = '%.0f'%(data.tUserMode*1000)
|
||||
last_init = '%.0f'%(tTotal*1000)
|
||||
|
@ -734,7 +738,7 @@ def updateCron(restore=False):
|
|||
op.close()
|
||||
res = call([cmd, cronfile])
|
||||
except Exception, e:
|
||||
print 'Exception: %s' % str(e)
|
||||
pprint('Exception: %s' % str(e))
|
||||
shutil.move(backfile, cronfile)
|
||||
res = -1
|
||||
if res != 0:
|
||||
|
@ -750,7 +754,7 @@ def updateGrub(restore=False):
|
|||
call(sysvals.blexec, stderr=PIPE, stdout=PIPE,
|
||||
env={'PATH': '.:/sbin:/usr/sbin:/usr/bin:/sbin:/bin'})
|
||||
except Exception, e:
|
||||
print 'Exception: %s\n' % str(e)
|
||||
pprint('Exception: %s\n' % str(e))
|
||||
return
|
||||
# extract the option and create a grub config without it
|
||||
sysvals.rootUser(True)
|
||||
|
@ -797,7 +801,7 @@ def updateGrub(restore=False):
|
|||
res = call(sysvals.blexec)
|
||||
os.remove(grubfile)
|
||||
except Exception, e:
|
||||
print 'Exception: %s' % str(e)
|
||||
pprint('Exception: %s' % str(e))
|
||||
res = -1
|
||||
# cleanup
|
||||
shutil.move(tempfile, grubfile)
|
||||
|
@ -821,7 +825,7 @@ def updateKernelParams(restore=False):
|
|||
def doError(msg, help=False):
|
||||
if help == True:
|
||||
printHelp()
|
||||
print 'ERROR: %s\n' % msg
|
||||
pprint('ERROR: %s\n' % msg)
|
||||
sysvals.outputResult({'error':msg})
|
||||
sys.exit()
|
||||
|
||||
|
@ -829,52 +833,51 @@ def doError(msg, help=False):
|
|||
# Description:
|
||||
# print out the help text
|
||||
def printHelp():
|
||||
print('')
|
||||
print('%s v%s' % (sysvals.title, sysvals.version))
|
||||
print('Usage: bootgraph <options> <command>')
|
||||
print('')
|
||||
print('Description:')
|
||||
print(' This tool reads in a dmesg log of linux kernel boot and')
|
||||
print(' creates an html representation of the boot timeline up to')
|
||||
print(' the start of the init process.')
|
||||
print('')
|
||||
print(' If no specific command is given the tool reads the current dmesg')
|
||||
print(' and/or ftrace log and creates a timeline')
|
||||
print('')
|
||||
print(' Generates output files in subdirectory: boot-yymmdd-HHMMSS')
|
||||
print(' HTML output: <hostname>_boot.html')
|
||||
print(' raw dmesg output: <hostname>_boot_dmesg.txt')
|
||||
print(' raw ftrace output: <hostname>_boot_ftrace.txt')
|
||||
print('')
|
||||
print('Options:')
|
||||
print(' -h Print this help text')
|
||||
print(' -v Print the current tool version')
|
||||
print(' -verbose Print extra information during execution and analysis')
|
||||
print(' -addlogs Add the dmesg log to the html output')
|
||||
print(' -result fn Export a results table to a text file for parsing.')
|
||||
print(' -o name Overrides the output subdirectory name when running a new test')
|
||||
print(' default: boot-{date}-{time}')
|
||||
print(' [advanced]')
|
||||
print(' -fstat Use ftrace to add function detail and statistics (default: disabled)')
|
||||
print(' -f/-callgraph Add callgraph detail, can be very large (default: disabled)')
|
||||
print(' -maxdepth N limit the callgraph data to N call levels (default: 2)')
|
||||
print(' -mincg ms Discard all callgraphs shorter than ms milliseconds (e.g. 0.001 for us)')
|
||||
print(' -timeprec N Number of significant digits in timestamps (0:S, 3:ms, [6:us])')
|
||||
print(' -expandcg pre-expand the callgraph data in the html output (default: disabled)')
|
||||
print(' -func list Limit ftrace to comma-delimited list of functions (default: do_one_initcall)')
|
||||
print(' -cgfilter S Filter the callgraph output in the timeline')
|
||||
print(' -cgskip file Callgraph functions to skip, off to disable (default: cgskip.txt)')
|
||||
print(' -bl name Use the following boot loader for kernel params (default: grub)')
|
||||
print(' -reboot Reboot the machine automatically and generate a new timeline')
|
||||
print(' -manual Show the steps to generate a new timeline manually (used with -reboot)')
|
||||
print('')
|
||||
print('Other commands:')
|
||||
print(' -flistall Print all functions capable of being captured in ftrace')
|
||||
print(' -sysinfo Print out system info extracted from BIOS')
|
||||
print(' [redo]')
|
||||
print(' -dmesg file Create HTML output using dmesg input (used with -ftrace)')
|
||||
print(' -ftrace file Create HTML output using ftrace input (used with -dmesg)')
|
||||
print('')
|
||||
pprint('\n%s v%s\n'\
|
||||
'Usage: bootgraph <options> <command>\n'\
|
||||
'\n'\
|
||||
'Description:\n'\
|
||||
' This tool reads in a dmesg log of linux kernel boot and\n'\
|
||||
' creates an html representation of the boot timeline up to\n'\
|
||||
' the start of the init process.\n'\
|
||||
'\n'\
|
||||
' If no specific command is given the tool reads the current dmesg\n'\
|
||||
' and/or ftrace log and creates a timeline\n'\
|
||||
'\n'\
|
||||
' Generates output files in subdirectory: boot-yymmdd-HHMMSS\n'\
|
||||
' HTML output: <hostname>_boot.html\n'\
|
||||
' raw dmesg output: <hostname>_boot_dmesg.txt\n'\
|
||||
' raw ftrace output: <hostname>_boot_ftrace.txt\n'\
|
||||
'\n'\
|
||||
'Options:\n'\
|
||||
' -h Print this help text\n'\
|
||||
' -v Print the current tool version\n'\
|
||||
' -verbose Print extra information during execution and analysis\n'\
|
||||
' -addlogs Add the dmesg log to the html output\n'\
|
||||
' -result fn Export a results table to a text file for parsing.\n'\
|
||||
' -o name Overrides the output subdirectory name when running a new test\n'\
|
||||
' default: boot-{date}-{time}\n'\
|
||||
' [advanced]\n'\
|
||||
' -fstat Use ftrace to add function detail and statistics (default: disabled)\n'\
|
||||
' -f/-callgraph Add callgraph detail, can be very large (default: disabled)\n'\
|
||||
' -maxdepth N limit the callgraph data to N call levels (default: 2)\n'\
|
||||
' -mincg ms Discard all callgraphs shorter than ms milliseconds (e.g. 0.001 for us)\n'\
|
||||
' -timeprec N Number of significant digits in timestamps (0:S, 3:ms, [6:us])\n'\
|
||||
' -expandcg pre-expand the callgraph data in the html output (default: disabled)\n'\
|
||||
' -func list Limit ftrace to comma-delimited list of functions (default: do_one_initcall)\n'\
|
||||
' -cgfilter S Filter the callgraph output in the timeline\n'\
|
||||
' -cgskip file Callgraph functions to skip, off to disable (default: cgskip.txt)\n'\
|
||||
' -bl name Use the following boot loader for kernel params (default: grub)\n'\
|
||||
' -reboot Reboot the machine automatically and generate a new timeline\n'\
|
||||
' -manual Show the steps to generate a new timeline manually (used with -reboot)\n'\
|
||||
'\n'\
|
||||
'Other commands:\n'\
|
||||
' -flistall Print all functions capable of being captured in ftrace\n'\
|
||||
' -sysinfo Print out system info extracted from BIOS\n'\
|
||||
' [redo]\n'\
|
||||
' -dmesg file Create HTML output using dmesg input (used with -ftrace)\n'\
|
||||
' -ftrace file Create HTML output using ftrace input (used with -dmesg)\n'\
|
||||
'' % (sysvals.title, sysvals.version))
|
||||
return True
|
||||
|
||||
# ----------------- MAIN --------------------
|
||||
|
@ -895,7 +898,7 @@ if __name__ == '__main__':
|
|||
printHelp()
|
||||
sys.exit()
|
||||
elif(arg == '-v'):
|
||||
print("Version %s" % sysvals.version)
|
||||
pprint("Version %s" % sysvals.version)
|
||||
sys.exit()
|
||||
elif(arg == '-verbose'):
|
||||
sysvals.verbose = True
|
||||
|
@ -1016,7 +1019,7 @@ if __name__ == '__main__':
|
|||
print f
|
||||
elif cmd == 'checkbl':
|
||||
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'):
|
||||
sysvals.printSystemInfo(True)
|
||||
sys.exit()
|
||||
|
|
|
@ -27,6 +27,7 @@ ktime_get
|
|||
# console calls
|
||||
printk
|
||||
dev_printk
|
||||
__dev_printk
|
||||
console_unlock
|
||||
|
||||
# memory handling
|
||||
|
|
|
@ -105,7 +105,7 @@ override-dev-timeline-functions: true
|
|||
# example: [color=#CC00CC]
|
||||
#
|
||||
# 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
|
||||
#
|
||||
|
@ -170,7 +170,7 @@ pm_restore_console:
|
|||
# example: [color=#CC00CC]
|
||||
#
|
||||
# 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
|
||||
#
|
||||
|
|
|
@ -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
|
||||
after the test is complete.
|
||||
.TP
|
||||
\fB-display \fIon/off\fR
|
||||
Turn the display on or off for the test using the xset command. This helps
|
||||
maintain the consistecy of test data for better comparison.
|
||||
\fB-display \fIon/off/standby/suspend\fR
|
||||
Switch the display to the requested mode for the test using the xset command.
|
||||
This helps maintain the consistency of test data for better comparison.
|
||||
.TP
|
||||
\fB-skiphtml\fR
|
||||
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.
|
|||
\fB-battery\fR
|
||||
Print out battery status and current charge.
|
||||
.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
|
||||
Print out system info extracted from BIOS. Reads /dev/mem directly instead of going through dmidecode.
|
||||
.TP
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue