Commit cf3c8f84 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'pm-5.6-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull more power manadement updates from Rafael Wysocki:
 "Prevent cpufreq from creating excessively large stack frames and fix
  the handling of devices deleted during system-wide resume in the PM
  core (Rafael Wysocki), revert a problematic commit affecting the
  cpupower utility and correct its man page (Thomas Renninger,
  Brahadambal Srinivasan), and improve the intel_pstate_tracer utility
  (Doug Smythies)"

* tag 'pm-5.6-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  tools/power/x86/intel_pstate_tracer: change several graphs to autoscale y-axis
  tools/power/x86/intel_pstate_tracer: changes for python 3 compatibility
  Correction to manpage of cpupower
  cpufreq: Avoid creating excessively large stack frames
  PM: core: Fix handling of devices deleted during system-wide resume
  cpupower: Revert library ABI changes from commit ae291709
parents a62aa6f7 82b2c6ff
...@@ -273,10 +273,38 @@ static void dpm_wait_for_suppliers(struct device *dev, bool async) ...@@ -273,10 +273,38 @@ static void dpm_wait_for_suppliers(struct device *dev, bool async)
device_links_read_unlock(idx); device_links_read_unlock(idx);
} }
static void dpm_wait_for_superior(struct device *dev, bool async) static bool dpm_wait_for_superior(struct device *dev, bool async)
{ {
dpm_wait(dev->parent, async); struct device *parent;
/*
* If the device is resumed asynchronously and the parent's callback
* deletes both the device and the parent itself, the parent object may
* be freed while this function is running, so avoid that by reference
* counting the parent once more unless the device has been deleted
* already (in which case return right away).
*/
mutex_lock(&dpm_list_mtx);
if (!device_pm_initialized(dev)) {
mutex_unlock(&dpm_list_mtx);
return false;
}
parent = get_device(dev->parent);
mutex_unlock(&dpm_list_mtx);
dpm_wait(parent, async);
put_device(parent);
dpm_wait_for_suppliers(dev, async); dpm_wait_for_suppliers(dev, async);
/*
* If the parent's callback has deleted the device, attempting to resume
* it would be invalid, so avoid doing that then.
*/
return device_pm_initialized(dev);
} }
static void dpm_wait_for_consumers(struct device *dev, bool async) static void dpm_wait_for_consumers(struct device *dev, bool async)
...@@ -621,7 +649,8 @@ static int device_resume_noirq(struct device *dev, pm_message_t state, bool asyn ...@@ -621,7 +649,8 @@ static int device_resume_noirq(struct device *dev, pm_message_t state, bool asyn
if (!dev->power.is_noirq_suspended) if (!dev->power.is_noirq_suspended)
goto Out; goto Out;
dpm_wait_for_superior(dev, async); if (!dpm_wait_for_superior(dev, async))
goto Out;
skip_resume = dev_pm_may_skip_resume(dev); skip_resume = dev_pm_may_skip_resume(dev);
...@@ -829,7 +858,8 @@ static int device_resume_early(struct device *dev, pm_message_t state, bool asyn ...@@ -829,7 +858,8 @@ static int device_resume_early(struct device *dev, pm_message_t state, bool asyn
if (!dev->power.is_late_suspended) if (!dev->power.is_late_suspended)
goto Out; goto Out;
dpm_wait_for_superior(dev, async); if (!dpm_wait_for_superior(dev, async))
goto Out;
callback = dpm_subsys_resume_early_cb(dev, state, &info); callback = dpm_subsys_resume_early_cb(dev, state, &info);
...@@ -944,7 +974,9 @@ static int device_resume(struct device *dev, pm_message_t state, bool async) ...@@ -944,7 +974,9 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
goto Complete; goto Complete;
} }
dpm_wait_for_superior(dev, async); if (!dpm_wait_for_superior(dev, async))
goto Complete;
dpm_watchdog_set(&wd, dev); dpm_watchdog_set(&wd, dev);
device_lock(dev); device_lock(dev);
......
...@@ -221,7 +221,7 @@ static int cppc_cpufreq_set_target(struct cpufreq_policy *policy, ...@@ -221,7 +221,7 @@ static int cppc_cpufreq_set_target(struct cpufreq_policy *policy,
return ret; return ret;
} }
static int cppc_verify_policy(struct cpufreq_policy *policy) static int cppc_verify_policy(struct cpufreq_policy_data *policy)
{ {
cpufreq_verify_within_cpu_limits(policy); cpufreq_verify_within_cpu_limits(policy);
return 0; return 0;
......
...@@ -291,7 +291,7 @@ static int nforce2_target(struct cpufreq_policy *policy, ...@@ -291,7 +291,7 @@ static int nforce2_target(struct cpufreq_policy *policy,
* nforce2_verify - verifies a new CPUFreq policy * nforce2_verify - verifies a new CPUFreq policy
* @policy: new policy * @policy: new policy
*/ */
static int nforce2_verify(struct cpufreq_policy *policy) static int nforce2_verify(struct cpufreq_policy_data *policy)
{ {
unsigned int fsb_pol_max; unsigned int fsb_pol_max;
......
...@@ -74,6 +74,9 @@ static void cpufreq_exit_governor(struct cpufreq_policy *policy); ...@@ -74,6 +74,9 @@ static void cpufreq_exit_governor(struct cpufreq_policy *policy);
static int cpufreq_start_governor(struct cpufreq_policy *policy); static int cpufreq_start_governor(struct cpufreq_policy *policy);
static void cpufreq_stop_governor(struct cpufreq_policy *policy); static void cpufreq_stop_governor(struct cpufreq_policy *policy);
static void cpufreq_governor_limits(struct cpufreq_policy *policy); static void cpufreq_governor_limits(struct cpufreq_policy *policy);
static int cpufreq_set_policy(struct cpufreq_policy *policy,
struct cpufreq_governor *new_gov,
unsigned int new_pol);
/** /**
* Two notifier lists: the "policy" list is involved in the * Two notifier lists: the "policy" list is involved in the
...@@ -616,25 +619,22 @@ static struct cpufreq_governor *find_governor(const char *str_governor) ...@@ -616,25 +619,22 @@ static struct cpufreq_governor *find_governor(const char *str_governor)
return NULL; return NULL;
} }
static int cpufreq_parse_policy(char *str_governor, static unsigned int cpufreq_parse_policy(char *str_governor)
struct cpufreq_policy *policy)
{ {
if (!strncasecmp(str_governor, "performance", CPUFREQ_NAME_LEN)) { if (!strncasecmp(str_governor, "performance", CPUFREQ_NAME_LEN))
policy->policy = CPUFREQ_POLICY_PERFORMANCE; return CPUFREQ_POLICY_PERFORMANCE;
return 0;
} if (!strncasecmp(str_governor, "powersave", CPUFREQ_NAME_LEN))
if (!strncasecmp(str_governor, "powersave", CPUFREQ_NAME_LEN)) { return CPUFREQ_POLICY_POWERSAVE;
policy->policy = CPUFREQ_POLICY_POWERSAVE;
return 0; return CPUFREQ_POLICY_UNKNOWN;
}
return -EINVAL;
} }
/** /**
* cpufreq_parse_governor - parse a governor string only for has_target() * cpufreq_parse_governor - parse a governor string only for has_target()
* @str_governor: Governor name.
*/ */
static int cpufreq_parse_governor(char *str_governor, static struct cpufreq_governor *cpufreq_parse_governor(char *str_governor)
struct cpufreq_policy *policy)
{ {
struct cpufreq_governor *t; struct cpufreq_governor *t;
...@@ -648,7 +648,7 @@ static int cpufreq_parse_governor(char *str_governor, ...@@ -648,7 +648,7 @@ static int cpufreq_parse_governor(char *str_governor,
ret = request_module("cpufreq_%s", str_governor); ret = request_module("cpufreq_%s", str_governor);
if (ret) if (ret)
return -EINVAL; return NULL;
mutex_lock(&cpufreq_governor_mutex); mutex_lock(&cpufreq_governor_mutex);
...@@ -659,12 +659,7 @@ static int cpufreq_parse_governor(char *str_governor, ...@@ -659,12 +659,7 @@ static int cpufreq_parse_governor(char *str_governor,
mutex_unlock(&cpufreq_governor_mutex); mutex_unlock(&cpufreq_governor_mutex);
if (t) { return t;
policy->governor = t;
return 0;
}
return -EINVAL;
} }
/** /**
...@@ -765,28 +760,33 @@ static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf) ...@@ -765,28 +760,33 @@ static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf)
static ssize_t store_scaling_governor(struct cpufreq_policy *policy, static ssize_t store_scaling_governor(struct cpufreq_policy *policy,
const char *buf, size_t count) const char *buf, size_t count)
{ {
char str_governor[16];
int ret; int ret;
char str_governor[16];
struct cpufreq_policy new_policy;
memcpy(&new_policy, policy, sizeof(*policy));
ret = sscanf(buf, "%15s", str_governor); ret = sscanf(buf, "%15s", str_governor);
if (ret != 1) if (ret != 1)
return -EINVAL; return -EINVAL;
if (cpufreq_driver->setpolicy) { if (cpufreq_driver->setpolicy) {
if (cpufreq_parse_policy(str_governor, &new_policy)) unsigned int new_pol;
new_pol = cpufreq_parse_policy(str_governor);
if (!new_pol)
return -EINVAL; return -EINVAL;
ret = cpufreq_set_policy(policy, NULL, new_pol);
} else { } else {
if (cpufreq_parse_governor(str_governor, &new_policy)) struct cpufreq_governor *new_gov;
new_gov = cpufreq_parse_governor(str_governor);
if (!new_gov)
return -EINVAL; return -EINVAL;
}
ret = cpufreq_set_policy(policy, &new_policy); ret = cpufreq_set_policy(policy, new_gov,
CPUFREQ_POLICY_UNKNOWN);
if (new_policy.governor) module_put(new_gov->owner);
module_put(new_policy.governor->owner); }
return ret ? ret : count; return ret ? ret : count;
} }
...@@ -1053,40 +1053,33 @@ __weak struct cpufreq_governor *cpufreq_default_governor(void) ...@@ -1053,40 +1053,33 @@ __weak struct cpufreq_governor *cpufreq_default_governor(void)
static int cpufreq_init_policy(struct cpufreq_policy *policy) static int cpufreq_init_policy(struct cpufreq_policy *policy)
{ {
struct cpufreq_governor *gov = NULL, *def_gov = NULL; struct cpufreq_governor *def_gov = cpufreq_default_governor();
struct cpufreq_policy new_policy; struct cpufreq_governor *gov = NULL;
unsigned int pol = CPUFREQ_POLICY_UNKNOWN;
memcpy(&new_policy, policy, sizeof(*policy));
def_gov = cpufreq_default_governor();
if (has_target()) { if (has_target()) {
/* /* Update policy governor to the one used before hotplug. */
* Update governor of new_policy to the governor used before
* hotplug
*/
gov = find_governor(policy->last_governor); gov = find_governor(policy->last_governor);
if (gov) { if (gov) {
pr_debug("Restoring governor %s for cpu %d\n", pr_debug("Restoring governor %s for cpu %d\n",
policy->governor->name, policy->cpu); policy->governor->name, policy->cpu);
} else { } else if (def_gov) {
if (!def_gov)
return -ENODATA;
gov = def_gov; gov = def_gov;
} else {
return -ENODATA;
} }
new_policy.governor = gov;
} else { } else {
/* Use the default policy if there is no last_policy. */ /* Use the default policy if there is no last_policy. */
if (policy->last_policy) { if (policy->last_policy) {
new_policy.policy = policy->last_policy; pol = policy->last_policy;
} else if (def_gov) {
pol = cpufreq_parse_policy(def_gov->name);
} else { } else {
if (!def_gov) return -ENODATA;
return -ENODATA;
cpufreq_parse_policy(def_gov->name, &new_policy);
} }
} }
return cpufreq_set_policy(policy, &new_policy); return cpufreq_set_policy(policy, gov, pol);
} }
static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu) static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
...@@ -1114,13 +1107,10 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, unsigned int cp ...@@ -1114,13 +1107,10 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, unsigned int cp
void refresh_frequency_limits(struct cpufreq_policy *policy) void refresh_frequency_limits(struct cpufreq_policy *policy)
{ {
struct cpufreq_policy new_policy;
if (!policy_is_inactive(policy)) { if (!policy_is_inactive(policy)) {
new_policy = *policy;
pr_debug("updating policy for CPU %u\n", policy->cpu); pr_debug("updating policy for CPU %u\n", policy->cpu);
cpufreq_set_policy(policy, &new_policy); cpufreq_set_policy(policy, policy->governor, policy->policy);
} }
} }
EXPORT_SYMBOL(refresh_frequency_limits); EXPORT_SYMBOL(refresh_frequency_limits);
...@@ -2364,46 +2354,49 @@ EXPORT_SYMBOL(cpufreq_get_policy); ...@@ -2364,46 +2354,49 @@ EXPORT_SYMBOL(cpufreq_get_policy);
/** /**
* cpufreq_set_policy - Modify cpufreq policy parameters. * cpufreq_set_policy - Modify cpufreq policy parameters.
* @policy: Policy object to modify. * @policy: Policy object to modify.
* @new_policy: New policy data. * @new_gov: Policy governor pointer.
* @new_pol: Policy value (for drivers with built-in governors).
* *
* Pass @new_policy to the cpufreq driver's ->verify() callback. Next, copy the * Invoke the cpufreq driver's ->verify() callback to sanity-check the frequency
* min and max parameters of @new_policy to @policy and either invoke the * limits to be set for the policy, update @policy with the verified limits
* driver's ->setpolicy() callback (if present) or carry out a governor update * values and either invoke the driver's ->setpolicy() callback (if present) or
* for @policy. That is, run the current governor's ->limits() callback (if the * carry out a governor update for @policy. That is, run the current governor's
* governor field in @new_policy points to the same object as the one in * ->limits() callback (if @new_gov points to the same object as the one in
* @policy) or replace the governor for @policy with the new one stored in * @policy) or replace the governor for @policy with @new_gov.
* @new_policy.
* *
* The cpuinfo part of @policy is not updated by this function. * The cpuinfo part of @policy is not updated by this function.
*/ */
int cpufreq_set_policy(struct cpufreq_policy *policy, static int cpufreq_set_policy(struct cpufreq_policy *policy,
struct cpufreq_policy *new_policy) struct cpufreq_governor *new_gov,
unsigned int new_pol)
{ {
struct cpufreq_policy_data new_data;
struct cpufreq_governor *old_gov; struct cpufreq_governor *old_gov;
int ret; int ret;
pr_debug("setting new policy for CPU %u: %u - %u kHz\n", memcpy(&new_data.cpuinfo, &policy->cpuinfo, sizeof(policy->cpuinfo));
new_policy->cpu, new_policy->min, new_policy->max); new_data.freq_table = policy->freq_table;
new_data.cpu = policy->cpu;
memcpy(&new_policy->cpuinfo, &policy->cpuinfo, sizeof(policy->cpuinfo));
/* /*
* PM QoS framework collects all the requests from users and provide us * PM QoS framework collects all the requests from users and provide us
* the final aggregated value here. * the final aggregated value here.
*/ */
new_policy->min = freq_qos_read_value(&policy->constraints, FREQ_QOS_MIN); new_data.min = freq_qos_read_value(&policy->constraints, FREQ_QOS_MIN);
new_policy->max = freq_qos_read_value(&policy->constraints, FREQ_QOS_MAX); new_data.max = freq_qos_read_value(&policy->constraints, FREQ_QOS_MAX);
pr_debug("setting new policy for CPU %u: %u - %u kHz\n",
new_data.cpu, new_data.min, new_data.max);
/* /*
* Verify that the CPU speed can be set within these limits and make sure * Verify that the CPU speed can be set within these limits and make sure
* that min <= max. * that min <= max.
*/ */
ret = cpufreq_driver->verify(new_policy); ret = cpufreq_driver->verify(&new_data);
if (ret) if (ret)
return ret; return ret;
policy->min = new_policy->min; policy->min = new_data.min;
policy->max = new_policy->max; policy->max = new_data.max;
trace_cpu_frequency_limits(policy); trace_cpu_frequency_limits(policy);
policy->cached_target_freq = UINT_MAX; policy->cached_target_freq = UINT_MAX;
...@@ -2412,12 +2405,12 @@ int cpufreq_set_policy(struct cpufreq_policy *policy, ...@@ -2412,12 +2405,12 @@ int cpufreq_set_policy(struct cpufreq_policy *policy,
policy->min, policy->max); policy->min, policy->max);
if (cpufreq_driver->setpolicy) { if (cpufreq_driver->setpolicy) {
policy->policy = new_policy->policy; policy->policy = new_pol;
pr_debug("setting range\n"); pr_debug("setting range\n");
return cpufreq_driver->setpolicy(policy); return cpufreq_driver->setpolicy(policy);
} }
if (new_policy->governor == policy->governor) { if (new_gov == policy->governor) {
pr_debug("governor limits update\n"); pr_debug("governor limits update\n");
cpufreq_governor_limits(policy); cpufreq_governor_limits(policy);
return 0; return 0;
...@@ -2434,7 +2427,7 @@ int cpufreq_set_policy(struct cpufreq_policy *policy, ...@@ -2434,7 +2427,7 @@ int cpufreq_set_policy(struct cpufreq_policy *policy,
} }
/* start new governor */ /* start new governor */
policy->governor = new_policy->governor; policy->governor = new_gov;
ret = cpufreq_init_governor(policy); ret = cpufreq_init_governor(policy);
if (!ret) { if (!ret) {
ret = cpufreq_start_governor(policy); ret = cpufreq_start_governor(policy);
......
...@@ -60,7 +60,7 @@ int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy, ...@@ -60,7 +60,7 @@ int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
return 0; return 0;
} }
int cpufreq_frequency_table_verify(struct cpufreq_policy *policy, int cpufreq_frequency_table_verify(struct cpufreq_policy_data *policy,
struct cpufreq_frequency_table *table) struct cpufreq_frequency_table *table)
{ {
struct cpufreq_frequency_table *pos; struct cpufreq_frequency_table *pos;
...@@ -100,7 +100,7 @@ EXPORT_SYMBOL_GPL(cpufreq_frequency_table_verify); ...@@ -100,7 +100,7 @@ EXPORT_SYMBOL_GPL(cpufreq_frequency_table_verify);
* Generic routine to verify policy & frequency table, requires driver to set * Generic routine to verify policy & frequency table, requires driver to set
* policy->freq_table prior to it. * policy->freq_table prior to it.
*/ */
int cpufreq_generic_frequency_table_verify(struct cpufreq_policy *policy) int cpufreq_generic_frequency_table_verify(struct cpufreq_policy_data *policy)
{ {
if (!policy->freq_table) if (!policy->freq_table)
return -ENODEV; return -ENODEV;
......
...@@ -328,7 +328,7 @@ static void gx_set_cpuspeed(struct cpufreq_policy *policy, unsigned int khz) ...@@ -328,7 +328,7 @@ static void gx_set_cpuspeed(struct cpufreq_policy *policy, unsigned int khz)
* for the hardware supported by the driver. * for the hardware supported by the driver.
*/ */
static int cpufreq_gx_verify(struct cpufreq_policy *policy) static int cpufreq_gx_verify(struct cpufreq_policy_data *policy)
{ {
unsigned int tmp_freq = 0; unsigned int tmp_freq = 0;
u8 tmp1, tmp2; u8 tmp1, tmp2;
......
...@@ -2036,8 +2036,9 @@ static int intel_pstate_get_max_freq(struct cpudata *cpu) ...@@ -2036,8 +2036,9 @@ static int intel_pstate_get_max_freq(struct cpudata *cpu)
cpu->pstate.max_freq : cpu->pstate.turbo_freq; cpu->pstate.max_freq : cpu->pstate.turbo_freq;
} }
static void intel_pstate_update_perf_limits(struct cpufreq_policy *policy, static void intel_pstate_update_perf_limits(struct cpudata *cpu,
struct cpudata *cpu) unsigned int policy_min,
unsigned int policy_max)
{ {
int max_freq = intel_pstate_get_max_freq(cpu); int max_freq = intel_pstate_get_max_freq(cpu);
int32_t max_policy_perf, min_policy_perf; int32_t max_policy_perf, min_policy_perf;
...@@ -2056,18 +2057,17 @@ static void intel_pstate_update_perf_limits(struct cpufreq_policy *policy, ...@@ -2056,18 +2057,17 @@ static void intel_pstate_update_perf_limits(struct cpufreq_policy *policy,
turbo_max = cpu->pstate.turbo_pstate; turbo_max = cpu->pstate.turbo_pstate;
} }
max_policy_perf = max_state * policy->max / max_freq; max_policy_perf = max_state * policy_max / max_freq;
if (policy->max == policy->min) { if (policy_max == policy_min) {
min_policy_perf = max_policy_perf; min_policy_perf = max_policy_perf;
} else { } else {
min_policy_perf = max_state * policy->min / max_freq; min_policy_perf = max_state * policy_min / max_freq;
min_policy_perf = clamp_t(int32_t, min_policy_perf, min_policy_perf = clamp_t(int32_t, min_policy_perf,
0, max_policy_perf); 0, max_policy_perf);
} }
pr_debug("cpu:%d max_state %d min_policy_perf:%d max_policy_perf:%d\n", pr_debug("cpu:%d max_state %d min_policy_perf:%d max_policy_perf:%d\n",
policy->cpu, max_state, cpu->cpu, max_state, min_policy_perf, max_policy_perf);
min_policy_perf, max_policy_perf);
/* Normalize user input to [min_perf, max_perf] */ /* Normalize user input to [min_perf, max_perf] */
if (per_cpu_limits) { if (per_cpu_limits) {
...@@ -2081,7 +2081,7 @@ static void intel_pstate_update_perf_limits(struct cpufreq_policy *policy, ...@@ -2081,7 +2081,7 @@ static void intel_pstate_update_perf_limits(struct cpufreq_policy *policy,
global_min = DIV_ROUND_UP(turbo_max * global.min_perf_pct, 100); global_min = DIV_ROUND_UP(turbo_max * global.min_perf_pct, 100);
global_min = clamp_t(int32_t, global_min, 0, global_max); global_min = clamp_t(int32_t, global_min, 0, global_max);
pr_debug("cpu:%d global_min:%d global_max:%d\n", policy->cpu, pr_debug("cpu:%d global_min:%d global_max:%d\n", cpu->cpu,
global_min, global_max); global_min, global_max);
cpu->min_perf_ratio = max(min_policy_perf, global_min); cpu->min_perf_ratio = max(min_policy_perf, global_min);
...@@ -2094,7 +2094,7 @@ static void intel_pstate_update_perf_limits(struct cpufreq_policy *policy, ...@@ -2094,7 +2094,7 @@ static void intel_pstate_update_perf_limits(struct cpufreq_policy *policy,
cpu->max_perf_ratio); cpu->max_perf_ratio);
} }
pr_debug("cpu:%d max_perf_ratio:%d min_perf_ratio:%d\n", policy->cpu, pr_debug("cpu:%d max_perf_ratio:%d min_perf_ratio:%d\n", cpu->cpu,
cpu->max_perf_ratio, cpu->max_perf_ratio,
cpu->min_perf_ratio); cpu->min_perf_ratio);
} }
...@@ -2114,7 +2114,7 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy) ...@@ -2114,7 +2114,7 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
mutex_lock(&intel_pstate_limits_lock); mutex_lock(&intel_pstate_limits_lock);
intel_pstate_update_perf_limits(policy, cpu); intel_pstate_update_perf_limits(cpu, policy->min, policy->max);
if (cpu->policy == CPUFREQ_POLICY_PERFORMANCE) { if (cpu->policy == CPUFREQ_POLICY_PERFORMANCE) {
/* /*
...@@ -2143,8 +2143,8 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy) ...@@ -2143,8 +2143,8 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
return 0; return 0;
} }
static void intel_pstate_adjust_policy_max(struct cpufreq_policy *policy, static void intel_pstate_adjust_policy_max(struct cpudata *cpu,
struct cpudata *cpu) struct cpufreq_policy_data *policy)
{ {
if (!hwp_active && if (!hwp_active &&
cpu->pstate.max_pstate_physical > cpu->pstate.max_pstate && cpu->pstate.max_pstate_physical > cpu->pstate.max_pstate &&
...@@ -2155,7 +2155,7 @@ static void intel_pstate_adjust_policy_max(struct cpufreq_policy *policy, ...@@ -2155,7 +2155,7 @@ static void intel_pstate_adjust_policy_max(struct cpufreq_policy *policy,
} }
} }
static int intel_pstate_verify_policy(struct cpufreq_policy *policy) static int intel_pstate_verify_policy(struct cpufreq_policy_data *policy)
{ {
struct cpudata *cpu = all_cpu_data[policy->cpu]; struct cpudata *cpu = all_cpu_data[policy->cpu];
...@@ -2163,11 +2163,7 @@ static int intel_pstate_verify_policy(struct cpufreq_policy *policy) ...@@ -2163,11 +2163,7 @@ static int intel_pstate_verify_policy(struct cpufreq_policy *policy)
cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
intel_pstate_get_max_freq(cpu)); intel_pstate_get_max_freq(cpu));
if (policy->policy != CPUFREQ_POLICY_POWERSAVE && intel_pstate_adjust_policy_max(cpu, policy);
policy->policy != CPUFREQ_POLICY_PERFORMANCE)
return -EINVAL;
intel_pstate_adjust_policy_max(policy, cpu);
return 0; return 0;
} }
...@@ -2268,7 +2264,7 @@ static struct cpufreq_driver intel_pstate = { ...@@ -2268,7 +2264,7 @@ static struct cpufreq_driver intel_pstate = {
.name = "intel_pstate", .name = "intel_pstate",
}; };
static int intel_cpufreq_verify_policy(struct cpufreq_policy *policy) static int intel_cpufreq_verify_policy(struct cpufreq_policy_data *policy)
{ {
struct cpudata *cpu = all_cpu_data[policy->cpu]; struct cpudata *cpu = all_cpu_data[policy->cpu];
...@@ -2276,9 +2272,9 @@ static int intel_cpufreq_verify_policy(struct cpufreq_policy *policy) ...@@ -2276,9 +2272,9 @@ static int intel_cpufreq_verify_policy(struct cpufreq_policy *policy)
cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
intel_pstate_get_max_freq(cpu)); intel_pstate_get_max_freq(cpu));
intel_pstate_adjust_policy_max(policy, cpu); intel_pstate_adjust_policy_max(cpu, policy);
intel_pstate_update_perf_limits(policy, cpu); intel_pstate_update_perf_limits(cpu, policy->min, policy->max);
return 0; return 0;
} }
......
...@@ -122,7 +122,7 @@ static int longrun_set_policy(struct cpufreq_policy *policy) ...@@ -122,7 +122,7 @@ static int longrun_set_policy(struct cpufreq_policy *policy)
* Validates a new CPUFreq policy. This function has to be called with * Validates a new CPUFreq policy. This function has to be called with
* cpufreq_driver locked. * cpufreq_driver locked.
*/ */
static int longrun_verify_policy(struct cpufreq_policy *policy) static int longrun_verify_policy(struct cpufreq_policy_data *policy)
{ {
if (!policy) if (!policy)
return -EINVAL; return -EINVAL;
...@@ -130,10 +130,6 @@ static int longrun_verify_policy(struct cpufreq_policy *policy) ...@@ -130,10 +130,6 @@ static int longrun_verify_policy(struct cpufreq_policy *policy)
policy->cpu = 0; policy->cpu = 0;
cpufreq_verify_within_cpu_limits(policy); cpufreq_verify_within_cpu_limits(policy);
if ((policy->policy != CPUFREQ_POLICY_POWERSAVE) &&
(policy->policy != CPUFREQ_POLICY_PERFORMANCE))
return -EINVAL;
return 0; return 0;
} }
......
...@@ -109,7 +109,7 @@ struct pcc_cpu { ...@@ -109,7 +109,7 @@ struct pcc_cpu {
static struct pcc_cpu __percpu *pcc_cpu_info; static struct pcc_cpu __percpu *pcc_cpu_info;
static int pcc_cpufreq_verify(struct cpufreq_policy *policy) static int pcc_cpufreq_verify(struct cpufreq_policy_data *policy)
{ {
cpufreq_verify_within_cpu_limits(policy); cpufreq_verify_within_cpu_limits(policy);
return 0; return 0;
......
...@@ -87,7 +87,7 @@ static int sh_cpufreq_target(struct cpufreq_policy *policy, ...@@ -87,7 +87,7 @@ static int sh_cpufreq_target(struct cpufreq_policy *policy,
return work_on_cpu(policy->cpu, __sh_cpufreq_target, &data); return work_on_cpu(policy->cpu, __sh_cpufreq_target, &data);
} }
static int sh_cpufreq_verify(struct cpufreq_policy *policy) static int sh_cpufreq_verify(struct cpufreq_policy_data *policy)
{ {
struct clk *cpuclk = &per_cpu(sh_cpuclk, policy->cpu); struct clk *cpuclk = &per_cpu(sh_cpuclk, policy->cpu);
struct cpufreq_frequency_table *freq_table; struct cpufreq_frequency_table *freq_table;
......
...@@ -22,7 +22,7 @@ static struct cpufreq_driver ucv2_driver; ...@@ -22,7 +22,7 @@ static struct cpufreq_driver ucv2_driver;
/* make sure that only the "userspace" governor is run /* make sure that only the "userspace" governor is run
* -- anything else wouldn't make sense on this platform, anyway. * -- anything else wouldn't make sense on this platform, anyway.
*/ */
static int ucv2_verify_speed(struct cpufreq_policy *policy) static int ucv2_verify_speed(struct cpufreq_policy_data *policy)
{ {
if (policy->cpu) if (policy->cpu)
return -EINVAL; return -EINVAL;
......
...@@ -148,6 +148,20 @@ struct cpufreq_policy { ...@@ -148,6 +148,20 @@ struct cpufreq_policy {
struct notifier_block nb_max; struct notifier_block nb_max;
}; };
/*
* Used for passing new cpufreq policy data to the cpufreq driver's ->verify()
* callback for sanitization. That callback is only expected to modify the min
* and max values, if necessary, and specifically it must not update the
* frequency table.
*/
struct cpufreq_policy_data {
struct cpufreq_cpuinfo cpuinfo;
struct cpufreq_frequency_table *freq_table;
unsigned int cpu;
unsigned int min; /* in kHz */
unsigned int max; /* in kHz */
};
struct cpufreq_freqs { struct cpufreq_freqs {
struct cpufreq_policy *policy; struct cpufreq_policy *policy;
unsigned int old; unsigned int old;
...@@ -201,8 +215,6 @@ u64 get_cpu_idle_time(unsigned int cpu, u64 *wall, int io_busy); ...@@ -201,8 +215,6 @@ u64 get_cpu_idle_time(unsigned int cpu, u64 *wall, int io_busy);
struct cpufreq_policy *cpufreq_cpu_acquire(unsigned int cpu); struct cpufreq_policy *cpufreq_cpu_acquire(unsigned int cpu);
void cpufreq_cpu_release(struct cpufreq_policy *policy); void cpufreq_cpu_release(struct cpufreq_policy *policy);
int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu); int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu);
int cpufreq_set_policy(struct cpufreq_policy *policy,
struct cpufreq_policy *new_policy);
void refresh_frequency_limits(struct cpufreq_policy *policy); void refresh_frequency_limits(struct cpufreq_policy *policy);
void cpufreq_update_policy(unsigned int cpu); void cpufreq_update_policy(unsigned int cpu);
void cpufreq_update_limits(unsigned int cpu); void cpufreq_update_limits(unsigned int cpu);
...@@ -284,7 +296,7 @@ struct cpufreq_driver { ...@@ -284,7 +296,7 @@ struct cpufreq_driver {
/* needed by all drivers */ /* needed by all drivers */
int (*init)(struct cpufreq_policy *policy); int (*init)(struct cpufreq_policy *policy);
int (*verify)(struct cpufreq_policy *policy); int (*verify)(struct cpufreq_policy_data *policy);
/* define one out of two */ /* define one out of two */
int (*setpolicy)(struct cpufreq_policy *policy); int (*setpolicy)(struct cpufreq_policy *policy);
...@@ -415,8 +427,9 @@ static inline int cpufreq_thermal_control_enabled(struct cpufreq_driver *drv) ...@@ -415,8 +427,9 @@ static inline int cpufreq_thermal_control_enabled(struct cpufreq_driver *drv)
(drv->flags & CPUFREQ_IS_COOLING_DEV); (drv->flags & CPUFREQ_IS_COOLING_DEV);
} }
static inline void cpufreq_verify_within_limits(struct cpufreq_policy *policy, static inline void cpufreq_verify_within_limits(struct cpufreq_policy_data *policy,
unsigned int min, unsigned int max) unsigned int min,
unsigned int max)
{ {
if (policy->min < min) if (policy->min < min)
policy->min = min; policy->min = min;
...@@ -432,10 +445,10 @@ static inline void cpufreq_verify_within_limits(struct cpufreq_policy *policy, ...@@ -432,10 +445,10 @@ static inline void cpufreq_verify_within_limits(struct cpufreq_policy *policy,
} }
static inline void static inline void
cpufreq_verify_within_cpu_limits(struct cpufreq_policy *policy) cpufreq_verify_within_cpu_limits(struct cpufreq_policy_data *policy)
{ {
cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
policy->cpuinfo.max_freq); policy->cpuinfo.max_freq);
} }
#ifdef CONFIG_CPU_FREQ #ifdef CONFIG_CPU_FREQ
...@@ -513,6 +526,7 @@ static inline unsigned long cpufreq_scale(unsigned long old, u_int div, ...@@ -513,6 +526,7 @@ static inline unsigned long cpufreq_scale(unsigned long old, u_int div,
* CPUFREQ GOVERNORS * * CPUFREQ GOVERNORS *
*********************************************************************/ *********************************************************************/
#define CPUFREQ_POLICY_UNKNOWN (0)
/* /*
* If (cpufreq_driver->target) exists, the ->governor decides what frequency * If (cpufreq_driver->target) exists, the ->governor decides what frequency
* within the limits is used. If (cpufreq_driver->setpolicy> exists, these * within the limits is used. If (cpufreq_driver->setpolicy> exists, these
...@@ -684,9 +698,9 @@ static inline void dev_pm_opp_free_cpufreq_table(struct device *dev, ...@@ -684,9 +698,9 @@ static inline void dev_pm_opp_free_cpufreq_table(struct device *dev,
int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy, int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
struct cpufreq_frequency_table *table); struct cpufreq_frequency_table *table);
int cpufreq_frequency_table_verify(struct cpufreq_policy *policy, int cpufreq_frequency_table_verify(struct cpufreq_policy_data *policy,
struct cpufreq_frequency_table *table); struct cpufreq_frequency_table *table);
int cpufreq_generic_frequency_table_verify(struct cpufreq_policy *policy); int cpufreq_generic_frequency_table_verify(struct cpufreq_policy_data *policy);
int cpufreq_table_index_unsorted(struct cpufreq_policy *policy, int cpufreq_table_index_unsorted(struct cpufreq_policy *policy,
unsigned int target_freq, unsigned int target_freq,
......
...@@ -332,21 +332,74 @@ void cpufreq_put_available_governors(struct cpufreq_available_governors *any) ...@@ -332,21 +332,74 @@ void cpufreq_put_available_governors(struct cpufreq_available_governors *any)
} }
struct cpufreq_frequencies struct cpufreq_available_frequencies
*cpufreq_get_frequencies(const char *type, unsigned int cpu) *cpufreq_get_available_frequencies(unsigned int cpu)
{ {
struct cpufreq_frequencies *first = NULL; struct cpufreq_available_frequencies *first = NULL;
struct cpufreq_frequencies *current = NULL; struct cpufreq_available_frequencies *current = NULL;
char one_value[SYSFS_PATH_MAX]; char one_value[SYSFS_PATH_MAX];
char linebuf[MAX_LINE_LEN]; char linebuf[MAX_LINE_LEN];
char fname[MAX_LINE_LEN];
unsigned int pos, i; unsigned int pos, i;
unsigned int len; unsigned int len;
snprintf(fname, MAX_LINE_LEN, "scaling_%s_frequencies", type); len = sysfs_cpufreq_read_file(cpu, "scaling_available_frequencies",
linebuf, sizeof(linebuf));
if (len == 0)
return NULL;
len = sysfs_cpufreq_read_file(cpu, fname, pos = 0;
linebuf, sizeof(linebuf)); for (i = 0; i < len; i++) {
if (linebuf[i] == ' ' || linebuf[i] == '\n') {
if (i - pos < 2)
continue;
if (i - pos >= SYSFS_PATH_MAX)
goto error_out;
if (current) {
current->next = malloc(sizeof(*current));
if (!current->next)
goto error_out;
current = current->next;
} else {
first = malloc(sizeof(*first));
if (!first)
goto error_out;
current = first;
}
current->first = first;
current->next = NULL;
memcpy(one_value, linebuf + pos, i - pos);
one_value[i - pos] = '\0';
if (sscanf(one_value, "%lu", &current->frequency) != 1)
goto error_out;
pos = i + 1;
}
}
return first;
error_out:
while (first) {
current = first->next;
free(first);
first = current;
}
return NULL;
}
struct cpufreq_available_frequencies
*cpufreq_get_boost_frequencies(unsigned int cpu)
{
struct cpufreq_available_frequencies *first = NULL;
struct cpufreq_available_frequencies *current = NULL;
char one_value[SYSFS_PATH_MAX];
char linebuf[MAX_LINE_LEN];
unsigned int pos, i;
unsigned int len;
len = sysfs_cpufreq_read_file(cpu, "scaling_boost_frequencies",
linebuf, sizeof(linebuf));
if (len == 0) if (len == 0)
return NULL; return NULL;
...@@ -391,9 +444,9 @@ struct cpufreq_frequencies ...@@ -391,9 +444,9 @@ struct cpufreq_frequencies
return NULL; return NULL;
} }
void cpufreq_put_frequencies(struct cpufreq_frequencies *any) void cpufreq_put_available_frequencies(struct cpufreq_available_frequencies *any)
{ {
struct cpufreq_frequencies *tmp, *next; struct cpufreq_available_frequencies *tmp, *next;
if (!any) if (!any)
return; return;
...@@ -406,6 +459,11 @@ void cpufreq_put_frequencies(struct cpufreq_frequencies *any) ...@@ -406,6 +459,11 @@ void cpufreq_put_frequencies(struct cpufreq_frequencies *any)
} }
} }
void cpufreq_put_boost_frequencies(struct cpufreq_available_frequencies *any)
{
cpufreq_put_available_frequencies(any);
}
static struct cpufreq_affected_cpus *sysfs_get_cpu_list(unsigned int cpu, static struct cpufreq_affected_cpus *sysfs_get_cpu_list(unsigned int cpu,
const char *file) const char *file)
{ {
......
...@@ -20,10 +20,10 @@ struct cpufreq_available_governors { ...@@ -20,10 +20,10 @@ struct cpufreq_available_governors {
struct cpufreq_available_governors *first; struct cpufreq_available_governors *first;
}; };
struct cpufreq_frequencies { struct cpufreq_available_frequencies {
unsigned long frequency; unsigned long frequency;
struct cpufreq_frequencies *next; struct cpufreq_available_frequencies *next;
struct cpufreq_frequencies *first; struct cpufreq_available_frequencies *first;
}; };
...@@ -124,11 +124,17 @@ void cpufreq_put_available_governors( ...@@ -124,11 +124,17 @@ void cpufreq_put_available_governors(
* cpufreq_put_frequencies after use. * cpufreq_put_frequencies after use.
*/ */
struct cpufreq_frequencies struct cpufreq_available_frequencies
*cpufreq_get_frequencies(const char *type, unsigned int cpu); *cpufreq_get_available_frequencies(unsigned int cpu);
void cpufreq_put_frequencies( void cpufreq_put_available_frequencies(
struct cpufreq_frequencies *first); struct cpufreq_available_frequencies *first);
struct cpufreq_available_frequencies
*cpufreq_get_boost_frequencies(unsigned int cpu);
void cpufreq_put_boost_frequencies(
struct cpufreq_available_frequencies *first);
/* determine affected CPUs /* determine affected CPUs
......
...@@ -62,9 +62,9 @@ all cores ...@@ -62,9 +62,9 @@ all cores
Print the package name and version number. Print the package name and version number.
.SH "SEE ALSO" .SH "SEE ALSO"
cpupower-set(1), cpupower-info(1), cpupower-idle(1), cpupower-set(1), cpupower-info(1), cpupower-idle-info(1),
cpupower-frequency-set(1), cpupower-frequency-info(1), cpupower-monitor(1), cpupower-idle-set(1), cpupower-frequency-set(1), cpupower-frequency-info(1),
powertop(1) cpupower-monitor(1), powertop(1)
.PP .PP
.SH AUTHORS .SH AUTHORS
.nf .nf
......
...@@ -244,14 +244,14 @@ static int get_boost_mode_x86(unsigned int cpu) ...@@ -244,14 +244,14 @@ static int get_boost_mode_x86(unsigned int cpu)
static int get_boost_mode(unsigned int cpu) static int get_boost_mode(unsigned int cpu)
{ {
struct cpufreq_frequencies *freqs; struct cpufreq_available_frequencies *freqs;
if (cpupower_cpu_info.vendor == X86_VENDOR_AMD || if (cpupower_cpu_info.vendor == X86_VENDOR_AMD ||
cpupower_cpu_info.vendor == X86_VENDOR_HYGON || cpupower_cpu_info.vendor == X86_VENDOR_HYGON ||
cpupower_cpu_info.vendor == X86_VENDOR_INTEL) cpupower_cpu_info.vendor == X86_VENDOR_INTEL)
return get_boost_mode_x86(cpu); return get_boost_mode_x86(cpu);
freqs = cpufreq_get_frequencies("boost", cpu); freqs = cpufreq_get_boost_frequencies(cpu);
if (freqs) { if (freqs) {
printf(_(" boost frequency steps: ")); printf(_(" boost frequency steps: "));
while (freqs->next) { while (freqs->next) {
...@@ -261,7 +261,7 @@ static int get_boost_mode(unsigned int cpu) ...@@ -261,7 +261,7 @@ static int get_boost_mode(unsigned int cpu)
} }
print_speed(freqs->frequency); print_speed(freqs->frequency);
printf("\n"); printf("\n");
cpufreq_put_frequencies(freqs); cpufreq_put_available_frequencies(freqs);
} }
return 0; return 0;
...@@ -475,7 +475,7 @@ static int get_latency(unsigned int cpu, unsigned int human) ...@@ -475,7 +475,7 @@ static int get_latency(unsigned int cpu, unsigned int human)
static void debug_output_one(unsigned int cpu) static void debug_output_one(unsigned int cpu)
{ {
struct cpufreq_frequencies *freqs; struct cpufreq_available_frequencies *freqs;
get_driver(cpu); get_driver(cpu);
get_related_cpus(cpu); get_related_cpus(cpu);
...@@ -483,7 +483,7 @@ static void debug_output_one(unsigned int cpu) ...@@ -483,7 +483,7 @@ static void debug_output_one(unsigned int cpu)
get_latency(cpu, 1); get_latency(cpu, 1);
get_hardware_limits(cpu, 1); get_hardware_limits(cpu, 1);
freqs = cpufreq_get_frequencies("available", cpu); freqs = cpufreq_get_available_frequencies(cpu);
if (freqs) { if (freqs) {
printf(_(" available frequency steps: ")); printf(_(" available frequency steps: "));
while (freqs->next) { while (freqs->next) {
...@@ -493,7 +493,7 @@ static void debug_output_one(unsigned int cpu) ...@@ -493,7 +493,7 @@ static void debug_output_one(unsigned int cpu)
} }
print_speed(freqs->frequency); print_speed(freqs->frequency);
printf("\n"); printf("\n");
cpufreq_put_frequencies(freqs); cpufreq_put_available_frequencies(freqs);
} }
get_available_governors(cpu); get_available_governors(cpu);
......
...@@ -11,11 +11,11 @@ then this utility enables and collects trace data for a user specified interval ...@@ -11,11 +11,11 @@ then this utility enables and collects trace data for a user specified interval
and generates performance plots. and generates performance plots.
Prerequisites: Prerequisites:
Python version 2.7.x Python version 2.7.x or higher
gnuplot 5.0 or higher gnuplot 5.0 or higher
gnuplot-py 1.8 gnuplot-py 1.8 or higher
(Most of the distributions have these required packages. They may be called (Most of the distributions have these required packages. They may be called
gnuplot-py, phython-gnuplot. ) gnuplot-py, phython-gnuplot or phython3-gnuplot, gnuplot-nox, ... )
HWP (Hardware P-States are disabled) HWP (Hardware P-States are disabled)
Kernel config for Linux trace is enabled Kernel config for Linux trace is enabled
...@@ -104,7 +104,7 @@ def plot_perf_busy_with_sample(cpu_index): ...@@ -104,7 +104,7 @@ def plot_perf_busy_with_sample(cpu_index):
if os.path.exists(file_name): if os.path.exists(file_name):
output_png = "cpu%03d_perf_busy_vs_samples.png" % cpu_index output_png = "cpu%03d_perf_busy_vs_samples.png" % cpu_index
g_plot = common_all_gnuplot_settings(output_png) g_plot = common_all_gnuplot_settings(output_png)
g_plot('set yrange [0:40]') # autoscale this one, no set y1 range
g_plot('set y2range [0:200]') g_plot('set y2range [0:200]')
g_plot('set y2tics 0, 10') g_plot('set y2tics 0, 10')
g_plot('set title "{} : cpu perf busy vs. sample : CPU {:0>3} : {:%F %H:%M}"'.format(testname, cpu_index, datetime.now())) g_plot('set title "{} : cpu perf busy vs. sample : CPU {:0>3} : {:%F %H:%M}"'.format(testname, cpu_index, datetime.now()))
...@@ -125,7 +125,7 @@ def plot_perf_busy(cpu_index): ...@@ -125,7 +125,7 @@ def plot_perf_busy(cpu_index):
if os.path.exists(file_name): if os.path.exists(file_name):
output_png = "cpu%03d_perf_busy.png" % cpu_index output_png = "cpu%03d_perf_busy.png" % cpu_index
g_plot = common_all_gnuplot_settings(output_png) g_plot = common_all_gnuplot_settings(output_png)
g_plot('set yrange [0:40]') # autoscale this one, no set y1 range
g_plot('set y2range [0:200]') g_plot('set y2range [0:200]')
g_plot('set y2tics 0, 10') g_plot('set y2tics 0, 10')
g_plot('set title "{} : perf busy : CPU {:0>3} : {:%F %H:%M}"'.format(testname, cpu_index, datetime.now())) g_plot('set title "{} : perf busy : CPU {:0>3} : {:%F %H:%M}"'.format(testname, cpu_index, datetime.now()))
...@@ -144,9 +144,7 @@ def plot_durations(cpu_index): ...@@ -144,9 +144,7 @@ def plot_durations(cpu_index):
if os.path.exists(file_name): if os.path.exists(file_name):
output_png = "cpu%03d_durations.png" % cpu_index output_png = "cpu%03d_durations.png" % cpu_index
g_plot = common_all_gnuplot_settings(output_png) g_plot = common_all_gnuplot_settings(output_png)
# Should autoscale be used here? Should seconds be used here? # autoscale this one, no set y range
g_plot('set yrange [0:5000]')
g_plot('set ytics 0, 500')
g_plot('set title "{} : durations : CPU {:0>3} : {:%F %H:%M}"'.format(testname, cpu_index, datetime.now())) g_plot('set title "{} : durations : CPU {:0>3} : {:%F %H:%M}"'.format(testname, cpu_index, datetime.now()))
g_plot('set ylabel "Timer Duration (MilliSeconds)"') g_plot('set ylabel "Timer Duration (MilliSeconds)"')
# override common # override common
...@@ -176,12 +174,12 @@ def plot_pstate_cpu_with_sample(): ...@@ -176,12 +174,12 @@ def plot_pstate_cpu_with_sample():
if os.path.exists('cpu.csv'): if os.path.exists('cpu.csv'):
output_png = 'all_cpu_pstates_vs_samples.png' output_png = 'all_cpu_pstates_vs_samples.png'
g_plot = common_all_gnuplot_settings(output_png) g_plot = common_all_gnuplot_settings(output_png)
g_plot('set yrange [0:40]') # autoscale this one, no set y range
# override common # override common
g_plot('set xlabel "Samples"') g_plot('set xlabel "Samples"')
g_plot('set ylabel "P-State"') g_plot('set ylabel "P-State"')
g_plot('set title "{} : cpu pstate vs. sample : {:%F %H:%M}"'.format(testname, datetime.now())) g_plot('set title "{} : cpu pstate vs. sample : {:%F %H:%M}"'.format(testname, datetime.now()))
title_list = subprocess.check_output('ls cpu???.csv | sed -e \'s/.csv//\'',shell=True).replace('\n', ' ') title_list = subprocess.check_output('ls cpu???.csv | sed -e \'s/.csv//\'',shell=True).decode('utf-8').replace('\n', ' ')
plot_str = "plot for [i in title_list] i.'.csv' using {:d}:{:d} pt 7 ps 1 title i".format(C_SAMPLE, C_TO) plot_str = "plot for [i in title_list] i.'.csv' using {:d}:{:d} pt 7 ps 1 title i".format(C_SAMPLE, C_TO)
g_plot('title_list = "{}"'.format(title_list)) g_plot('title_list = "{}"'.format(title_list))
g_plot(plot_str) g_plot(plot_str)
...@@ -191,14 +189,14 @@ def plot_pstate_cpu(): ...@@ -191,14 +189,14 @@ def plot_pstate_cpu():
output_png = 'all_cpu_pstates.png' output_png = 'all_cpu_pstates.png'
g_plot = common_all_gnuplot_settings(output_png) g_plot = common_all_gnuplot_settings(output_png)
g_plot('set yrange [0:40]') # autoscale this one, no set y range
g_plot('set ylabel "P-State"') g_plot('set ylabel "P-State"')
g_plot('set title "{} : cpu pstates : {:%F %H:%M}"'.format(testname, datetime.now())) g_plot('set title "{} : cpu pstates : {:%F %H:%M}"'.format(testname, datetime.now()))
# the following command is really cool, but doesn't work with the CPU masking option because it aborts on the first missing file. # the following command is really cool, but doesn't work with the CPU masking option because it aborts on the first missing file.
# plot_str = 'plot for [i=0:*] file=sprintf("cpu%03d.csv",i) title_s=sprintf("cpu%03d",i) file using 16:7 pt 7 ps 1 title title_s' # plot_str = 'plot for [i=0:*] file=sprintf("cpu%03d.csv",i) title_s=sprintf("cpu%03d",i) file using 16:7 pt 7 ps 1 title title_s'
# #
title_list = subprocess.check_output('ls cpu???.csv | sed -e \'s/.csv//\'',shell=True).replace('\n', ' ') title_list = subprocess.check_output('ls cpu???.csv | sed -e \'s/.csv//\'',shell=True).decode('utf-8').replace('\n', ' ')
plot_str = "plot for [i in title_list] i.'.csv' using {:d}:{:d} pt 7 ps 1 title i".format(C_ELAPSED, C_TO) plot_str = "plot for [i in title_list] i.'.csv' using {:d}:{:d} pt 7 ps 1 title i".format(C_ELAPSED, C_TO)
g_plot('title_list = "{}"'.format(title_list)) g_plot('title_list = "{}"'.format(title_list))
g_plot(plot_str) g_plot(plot_str)
...@@ -212,7 +210,7 @@ def plot_load_cpu(): ...@@ -212,7 +210,7 @@ def plot_load_cpu():
g_plot('set ylabel "CPU load (percent)"') g_plot('set ylabel "CPU load (percent)"')
g_plot('set title "{} : cpu loads : {:%F %H:%M}"'.format(testname, datetime.now())) g_plot('set title "{} : cpu loads : {:%F %H:%M}"'.format(testname, datetime.now()))
title_list = subprocess.check_output('ls cpu???.csv | sed -e \'s/.csv//\'',shell=True).replace('\n', ' ') title_list = subprocess.check_output('ls cpu???.csv | sed -e \'s/.csv//\'',shell=True).decode('utf-8').replace('\n', ' ')
plot_str = "plot for [i in title_list] i.'.csv' using {:d}:{:d} pt 7 ps 1 title i".format(C_ELAPSED, C_LOAD) plot_str = "plot for [i in title_list] i.'.csv' using {:d}:{:d} pt 7 ps 1 title i".format(C_ELAPSED, C_LOAD)
g_plot('title_list = "{}"'.format(title_list)) g_plot('title_list = "{}"'.format(title_list))
g_plot(plot_str) g_plot(plot_str)
...@@ -222,11 +220,11 @@ def plot_frequency_cpu(): ...@@ -222,11 +220,11 @@ def plot_frequency_cpu():
output_png = 'all_cpu_frequencies.png' output_png = 'all_cpu_frequencies.png'
g_plot = common_all_gnuplot_settings(output_png) g_plot = common_all_gnuplot_settings(output_png)
g_plot('set yrange [0:4]') # autoscale this one, no set y range
g_plot('set ylabel "CPU Frequency (GHz)"') g_plot('set ylabel "CPU Frequency (GHz)"')
g_plot('set title "{} : cpu frequencies : {:%F %H:%M}"'.format(testname, datetime.now())) g_plot('set title "{} : cpu frequencies : {:%F %H:%M}"'.format(testname, datetime.now()))
title_list = subprocess.check_output('ls cpu???.csv | sed -e \'s/.csv//\'',shell=True).replace('\n', ' ') title_list = subprocess.check_output('ls cpu???.csv | sed -e \'s/.csv//\'',shell=True).decode('utf-8').replace('\n', ' ')
plot_str = "plot for [i in title_list] i.'.csv' using {:d}:{:d} pt 7 ps 1 title i".format(C_ELAPSED, C_FREQ) plot_str = "plot for [i in title_list] i.'.csv' using {:d}:{:d} pt 7 ps 1 title i".format(C_ELAPSED, C_FREQ)
g_plot('title_list = "{}"'.format(title_list)) g_plot('title_list = "{}"'.format(title_list))
g_plot(plot_str) g_plot(plot_str)
...@@ -236,12 +234,12 @@ def plot_duration_cpu(): ...@@ -236,12 +234,12 @@ def plot_duration_cpu():
output_png = 'all_cpu_durations.png' output_png = 'all_cpu_durations.png'
g_plot = common_all_gnuplot_settings(output_png) g_plot = common_all_gnuplot_settings(output_png)
g_plot('set yrange [0:5000]') # autoscale this one, no set y range
g_plot('set ytics 0, 500') g_plot('set ytics 0, 500')
g_plot('set ylabel "Timer Duration (MilliSeconds)"') g_plot('set ylabel "Timer Duration (MilliSeconds)"')
g_plot('set title "{} : cpu durations : {:%F %H:%M}"'.format(testname, datetime.now())) g_plot('set title "{} : cpu durations : {:%F %H:%M}"'.format(testname, datetime.now()))
title_list = subprocess.check_output('ls cpu???.csv | sed -e \'s/.csv//\'',shell=True).replace('\n', ' ') title_list = subprocess.check_output('ls cpu???.csv | sed -e \'s/.csv//\'',shell=True).decode('utf-8').replace('\n', ' ')
plot_str = "plot for [i in title_list] i.'.csv' using {:d}:{:d} pt 7 ps 1 title i".format(C_ELAPSED, C_DURATION) plot_str = "plot for [i in title_list] i.'.csv' using {:d}:{:d} pt 7 ps 1 title i".format(C_ELAPSED, C_DURATION)
g_plot('title_list = "{}"'.format(title_list)) g_plot('title_list = "{}"'.format(title_list))
g_plot(plot_str) g_plot(plot_str)
...@@ -255,7 +253,7 @@ def plot_scaled_cpu(): ...@@ -255,7 +253,7 @@ def plot_scaled_cpu():
g_plot('set ylabel "Scaled Busy (Unitless)"') g_plot('set ylabel "Scaled Busy (Unitless)"')
g_plot('set title "{} : cpu scaled busy : {:%F %H:%M}"'.format(testname, datetime.now())) g_plot('set title "{} : cpu scaled busy : {:%F %H:%M}"'.format(testname, datetime.now()))
title_list = subprocess.check_output('ls cpu???.csv | sed -e \'s/.csv//\'',shell=True).replace('\n', ' ') title_list = subprocess.check_output('ls cpu???.csv | sed -e \'s/.csv//\'',shell=True).decode('utf-8').replace('\n', ' ')
plot_str = "plot for [i in title_list] i.'.csv' using {:d}:{:d} pt 7 ps 1 title i".format(C_ELAPSED, C_SCALED) plot_str = "plot for [i in title_list] i.'.csv' using {:d}:{:d} pt 7 ps 1 title i".format(C_ELAPSED, C_SCALED)
g_plot('title_list = "{}"'.format(title_list)) g_plot('title_list = "{}"'.format(title_list))
g_plot(plot_str) g_plot(plot_str)
...@@ -269,7 +267,7 @@ def plot_boost_cpu(): ...@@ -269,7 +267,7 @@ def plot_boost_cpu():
g_plot('set ylabel "CPU IO Boost (percent)"') g_plot('set ylabel "CPU IO Boost (percent)"')
g_plot('set title "{} : cpu io boost : {:%F %H:%M}"'.format(testname, datetime.now())) g_plot('set title "{} : cpu io boost : {:%F %H:%M}"'.format(testname, datetime.now()))
title_list = subprocess.check_output('ls cpu???.csv | sed -e \'s/.csv//\'',shell=True).replace('\n', ' ') title_list = subprocess.check_output('ls cpu???.csv | sed -e \'s/.csv//\'',shell=True).decode('utf-8').replace('\n', ' ')
plot_str = "plot for [i in title_list] i.'.csv' using {:d}:{:d} pt 7 ps 1 title i".format(C_ELAPSED, C_BOOST) plot_str = "plot for [i in title_list] i.'.csv' using {:d}:{:d} pt 7 ps 1 title i".format(C_ELAPSED, C_BOOST)
g_plot('title_list = "{}"'.format(title_list)) g_plot('title_list = "{}"'.format(title_list))
g_plot(plot_str) g_plot(plot_str)
...@@ -283,7 +281,7 @@ def plot_ghz_cpu(): ...@@ -283,7 +281,7 @@ def plot_ghz_cpu():
g_plot('set ylabel "TSC Frequency (GHz)"') g_plot('set ylabel "TSC Frequency (GHz)"')
g_plot('set title "{} : cpu TSC Frequencies (Sanity check calculation) : {:%F %H:%M}"'.format(testname, datetime.now())) g_plot('set title "{} : cpu TSC Frequencies (Sanity check calculation) : {:%F %H:%M}"'.format(testname, datetime.now()))
title_list = subprocess.check_output('ls cpu???.csv | sed -e \'s/.csv//\'',shell=True).replace('\n', ' ') title_list = subprocess.check_output('ls cpu???.csv | sed -e \'s/.csv//\'',shell=True).decode('utf-8').replace('\n', ' ')
plot_str = "plot for [i in title_list] i.'.csv' using {:d}:{:d} pt 7 ps 1 title i".format(C_ELAPSED, C_GHZ) plot_str = "plot for [i in title_list] i.'.csv' using {:d}:{:d} pt 7 ps 1 title i".format(C_ELAPSED, C_GHZ)
g_plot('title_list = "{}"'.format(title_list)) g_plot('title_list = "{}"'.format(title_list))
g_plot(plot_str) g_plot(plot_str)
......
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