Power management updates for 6.13-rc1

- Update the amd-pstate driver to set the initial scaling frequency
    policy lower bound to be the lowest non-linear frequency (Dhananjay
    Ugwekar).
 
  - Enable amd-pstate by default on servers starting with newer AMD Epyc
    processors (Swapnil Sapkal).
 
  - Align more codepaths between shared memory and MSR designs in
    amd-pstate (Dhananjay Ugwekar).
 
  - Clean up amd-pstate code to rename functions and remove redundant
    calls (Dhananjay Ugwekar, Mario Limonciello).
 
  - Do other assorted fixes and cleanups in amd-pstate (Dhananjay Ugwekar
    and Mario Limonciello).
 
  - Change the Balance-performance EPP value for Granite Rapids in the
    intel_pstate driver to a more performance-biased one (Srinivas
    Pandruvada).
 
  - Simplify MSR read on the boot CPU in the ACPI cpufreq driver (Chang
    S. Bae).
 
  - Ensure sugov_eas_rebuild_sd() is always called when sugov_init()
    succeeds to always enforce sched domains rebuild in case EAS needs
    to be enabled (Christian Loehle).
 
  - Switch cpufreq back to platform_driver::remove() (Uwe Kleine-König).
 
  - Use proper frequency unit names in cpufreq (Marcin Juszkiewicz).
 
  - Add a built-in idle states table for Granite Rapids Xeon D to the
    intel_idle driver (Artem Bityutskiy).
 
  - Fix some typos in comments in the cpuidle core and drivers (Shen
    Lichuan).
 
  - Remove iowait influence from the menu cpuidle governor (Christian
    Loehle).
 
  - Add min/max available performance state limits to the Energy Model
    management code (Lukasz Luba).
 
  - Update pm-graph to v5.13 (Todd Brandt).
 
  - Add documentation for some recently introduced cpupower utility
    options (Tor Vic).
 
  - Make cpupower inform users where cpufreq-bench.conf should be located
    when opening it fails (Peng Fan).
 
  - Allow overriding cross-compiling env params in cpupower (Peng Fan).
 
  - Add compile_commands.json to .gitignore in cpupower (John B. Wyatt
    IV).
 
  - Improve disable c_state block in cpupower bindings and add a test to
    confirm that CPU state is disabled to it (John B. Wyatt IV).
 
  - Add Chinese Simplified translation to cpupower (Kieran Moy).
 
  - Add checks for xgettext and msgfmt to cpupower (Siddharth Menon).
 -----BEGIN PGP SIGNATURE-----
 
 iQJGBAABCAAwFiEE4fcc61cGeeHD/fCwgsRv/nhiVHEFAmc3r6sSHHJqd0Byand5
 c29ja2kubmV0AAoJEILEb/54YlRxQMUQALNEbh/Ko1d+avq0sfvyPw18BZjEiQw7
 M+L0GydLW6tXLYOrD+ZTASksdDhHbK0iuFr1Gca2cZi0Dl+1XF9sy70ITTqzCDIA
 8qj1JrPmRYI0KXCfiSSke0W9fU18IdxVX3I7XezVqBl0ICzsroN5wliCkmEnVOU9
 LQkw0fyYr7gev4GFEGSJ7WzfPxci0d6J9pYnafFlDEE28WpKz/cyOzYuSghX5lmG
 ISHIVNIM6lqNgXyQirConvhrlg60XAyw5k5jqAYZbe78T+dqhH7lr9sDi7c4XxkG
 syeiOOyjpiBMZv1rSjIUapi8AfJHyqH7B6KyTgiulIy31x8Dji62925B63CSahkM
 AminAq0lYkqbhIcqEr4sW0JQ/oW3iX4cZ3TJXTUL+vFByR0ZF81tgQcXufhrcvBs
 ViNugcX0q1vDX3lZsm9L6UHXN2yhUb36sgreUvbGfwnE79tuR/eUnAukTWBfXau/
 TWnyDiQn1CjZcfHB+YAPYZNyUHHqjoIJwzfJLwnsaHgFA80YcSwfSC9kcogCawK1
 NCyfs29lAccWsrOul5iARJu8pLw1X//UfDEmVNrBD+1hveKYMrjjiQXnPoVVnNhc
 J5T2q5S1QeO05+wf8WaZ7MbRNzHLj0A3gYHSVPWNclxFwsQjqCHHZS2qz8MTX+f6
 W6/eZuvmMbG7
 =w8QT
 -----END PGP SIGNATURE-----

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

Pull power management updates from Rafael Wysocki:
 "The amd-pstate cpufreq driver gets the majority of changes this time.
  They are mostly fixes and cleanups, but one of them causes it to
  become the default cpufreq driver on some AMD server platforms.

  Apart from that, the menu cpuidle governor is modified to not use
  iowait any more, the intel_idle gets a custom C-states table for
  Granite Rapids Xeon D, and the intel_pstate driver will use a more
  aggressive Balance- performance default EPP value on Granite Rapids
  now.

  There are also some fixes, cleanups and tooling updates.

  Specifics:

   - Update the amd-pstate driver to set the initial scaling frequency
     policy lower bound to be the lowest non-linear frequency (Dhananjay
     Ugwekar)

   - Enable amd-pstate by default on servers starting with newer AMD
     Epyc processors (Swapnil Sapkal)

   - Align more codepaths between shared memory and MSR designs in
     amd-pstate (Dhananjay Ugwekar)

   - Clean up amd-pstate code to rename functions and remove redundant
     calls (Dhananjay Ugwekar, Mario Limonciello)

   - Do other assorted fixes and cleanups in amd-pstate (Dhananjay
     Ugwekar and Mario Limonciello)

   - Change the Balance-performance EPP value for Granite Rapids in the
     intel_pstate driver to a more performance-biased one (Srinivas
     Pandruvada)

   - Simplify MSR read on the boot CPU in the ACPI cpufreq driver (Chang
     S. Bae)

   - Ensure sugov_eas_rebuild_sd() is always called when sugov_init()
     succeeds to always enforce sched domains rebuild in case EAS needs
     to be enabled (Christian Loehle)

   - Switch cpufreq back to platform_driver::remove() (Uwe Kleine-König)

   - Use proper frequency unit names in cpufreq (Marcin Juszkiewicz)

   - Add a built-in idle states table for Granite Rapids Xeon D to the
     intel_idle driver (Artem Bityutskiy)

   - Fix some typos in comments in the cpuidle core and drivers (Shen
     Lichuan)

   - Remove iowait influence from the menu cpuidle governor (Christian
     Loehle)

   - Add min/max available performance state limits to the Energy Model
     management code (Lukasz Luba)

   - Update pm-graph to v5.13 (Todd Brandt)

   - Add documentation for some recently introduced cpupower utility
     options (Tor Vic)

   - Make cpupower inform users where cpufreq-bench.conf should be
     located when opening it fails (Peng Fan)

   - Allow overriding cross-compiling env params in cpupower (Peng Fan)

   - Add compile_commands.json to .gitignore in cpupower (John B. Wyatt
     IV)

   - Improve disable c_state block in cpupower bindings and add a test
     to confirm that CPU state is disabled to it (John B. Wyatt IV)

   - Add Chinese Simplified translation to cpupower (Kieran Moy)

   - Add checks for xgettext and msgfmt to cpupower (Siddharth Menon)"

* tag 'pm-6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (38 commits)
  cpufreq: intel_pstate: Update Balance-performance EPP for Granite Rapids
  cpufreq: ACPI: Simplify MSR read on the boot CPU
  sched/cpufreq: Ensure sd is rebuilt for EAS check
  intel_idle: add Granite Rapids Xeon D support
  PM: EM: Add min/max available performance state limits
  cpufreq/amd-pstate: Move registration after static function call update
  cpufreq/amd-pstate: Push adjust_perf vfunc init into cpu_init
  cpufreq/amd-pstate: Align offline flow of shared memory and MSR based systems
  cpufreq/amd-pstate: Call cppc_set_epp_perf in the reenable function
  cpufreq/amd-pstate: Do not attempt to clear MSR_AMD_CPPC_ENABLE
  cpufreq/amd-pstate: Rename functions that enable CPPC
  cpufreq/amd-pstate-ut: Add fix for min freq unit test
  amd-pstate: Switch to amd-pstate by default on some Server platforms
  amd-pstate: Set min_perf to nominal_perf for active mode performance gov
  cpufreq/amd-pstate: Remove the redundant amd_pstate_set_driver() call
  cpufreq/amd-pstate: Remove the switch case in amd_pstate_init()
  cpufreq/amd-pstate: Call amd_pstate_set_driver() in amd_pstate_register_driver()
  cpufreq/amd-pstate: Call amd_pstate_register() in amd_pstate_init()
  cpufreq/amd-pstate: Set the initial min_freq to lowest_nonlinear_freq
  cpufreq/amd-pstate: Remove the redundant verify() function
  ...
This commit is contained in:
Linus Torvalds 2024-11-19 11:05:00 -08:00
commit ad52c55e1d
41 changed files with 1331 additions and 279 deletions

View File

@ -73,20 +73,17 @@ static unsigned int acpi_pstate_strict;
static bool boost_state(unsigned int cpu) static bool boost_state(unsigned int cpu)
{ {
u32 lo, hi;
u64 msr; u64 msr;
switch (boot_cpu_data.x86_vendor) { switch (boot_cpu_data.x86_vendor) {
case X86_VENDOR_INTEL: case X86_VENDOR_INTEL:
case X86_VENDOR_CENTAUR: case X86_VENDOR_CENTAUR:
case X86_VENDOR_ZHAOXIN: case X86_VENDOR_ZHAOXIN:
rdmsr_on_cpu(cpu, MSR_IA32_MISC_ENABLE, &lo, &hi); rdmsrl_on_cpu(cpu, MSR_IA32_MISC_ENABLE, &msr);
msr = lo | ((u64)hi << 32);
return !(msr & MSR_IA32_MISC_ENABLE_TURBO_DISABLE); return !(msr & MSR_IA32_MISC_ENABLE_TURBO_DISABLE);
case X86_VENDOR_HYGON: case X86_VENDOR_HYGON:
case X86_VENDOR_AMD: case X86_VENDOR_AMD:
rdmsr_on_cpu(cpu, MSR_K7_HWCR, &lo, &hi); rdmsrl_on_cpu(cpu, MSR_K7_HWCR, &msr);
msr = lo | ((u64)hi << 32);
return !(msr & MSR_K7_HWCR_CPB_DIS); return !(msr & MSR_K7_HWCR_CPB_DIS);
} }
return false; return false;
@ -1028,7 +1025,7 @@ static struct platform_driver acpi_cpufreq_platdrv = {
.driver = { .driver = {
.name = "acpi-cpufreq", .name = "acpi-cpufreq",
}, },
.remove_new = acpi_cpufreq_remove, .remove = acpi_cpufreq_remove,
}; };
static int __init acpi_cpufreq_init(void) static int __init acpi_cpufreq_init(void)

View File

@ -227,10 +227,10 @@ static void amd_pstate_ut_check_freq(u32 index)
goto skip_test; goto skip_test;
} }
if (cpudata->min_freq != policy->min) { if (cpudata->lowest_nonlinear_freq != policy->min) {
amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL;
pr_err("%s cpu%d cpudata_min_freq=%d policy_min=%d, they should be equal!\n", pr_err("%s cpu%d cpudata_lowest_nonlinear_freq=%d policy_min=%d, they should be equal!\n",
__func__, cpu, cpudata->min_freq, policy->min); __func__, cpu, cpudata->lowest_nonlinear_freq, policy->min);
goto skip_test; goto skip_test;
} }

View File

@ -233,7 +233,7 @@ static int amd_pstate_get_energy_pref_index(struct amd_cpudata *cpudata)
return index; return index;
} }
static void pstate_update_perf(struct amd_cpudata *cpudata, u32 min_perf, static void msr_update_perf(struct amd_cpudata *cpudata, u32 min_perf,
u32 des_perf, u32 max_perf, bool fast_switch) u32 des_perf, u32 max_perf, bool fast_switch)
{ {
if (fast_switch) if (fast_switch)
@ -243,7 +243,7 @@ static void pstate_update_perf(struct amd_cpudata *cpudata, u32 min_perf,
READ_ONCE(cpudata->cppc_req_cached)); READ_ONCE(cpudata->cppc_req_cached));
} }
DEFINE_STATIC_CALL(amd_pstate_update_perf, pstate_update_perf); DEFINE_STATIC_CALL(amd_pstate_update_perf, msr_update_perf);
static inline void amd_pstate_update_perf(struct amd_cpudata *cpudata, static inline void amd_pstate_update_perf(struct amd_cpudata *cpudata,
u32 min_perf, u32 des_perf, u32 min_perf, u32 des_perf,
@ -306,11 +306,17 @@ static int amd_pstate_set_energy_pref_index(struct amd_cpudata *cpudata,
return ret; return ret;
} }
static inline int pstate_enable(bool enable) static inline int msr_cppc_enable(bool enable)
{ {
int ret, cpu; int ret, cpu;
unsigned long logical_proc_id_mask = 0; unsigned long logical_proc_id_mask = 0;
/*
* MSR_AMD_CPPC_ENABLE is write-once, once set it cannot be cleared.
*/
if (!enable)
return 0;
if (enable == cppc_enabled) if (enable == cppc_enabled)
return 0; return 0;
@ -332,7 +338,7 @@ static inline int pstate_enable(bool enable)
return 0; return 0;
} }
static int cppc_enable(bool enable) static int shmem_cppc_enable(bool enable)
{ {
int cpu, ret = 0; int cpu, ret = 0;
struct cppc_perf_ctrls perf_ctrls; struct cppc_perf_ctrls perf_ctrls;
@ -359,14 +365,14 @@ static int cppc_enable(bool enable)
return ret; return ret;
} }
DEFINE_STATIC_CALL(amd_pstate_enable, pstate_enable); DEFINE_STATIC_CALL(amd_pstate_cppc_enable, msr_cppc_enable);
static inline int amd_pstate_enable(bool enable) static inline int amd_pstate_cppc_enable(bool enable)
{ {
return static_call(amd_pstate_enable)(enable); return static_call(amd_pstate_cppc_enable)(enable);
} }
static int pstate_init_perf(struct amd_cpudata *cpudata) static int msr_init_perf(struct amd_cpudata *cpudata)
{ {
u64 cap1; u64 cap1;
@ -385,7 +391,7 @@ static int pstate_init_perf(struct amd_cpudata *cpudata)
return 0; return 0;
} }
static int cppc_init_perf(struct amd_cpudata *cpudata) static int shmem_init_perf(struct amd_cpudata *cpudata)
{ {
struct cppc_perf_caps cppc_perf; struct cppc_perf_caps cppc_perf;
@ -420,14 +426,14 @@ static int cppc_init_perf(struct amd_cpudata *cpudata)
return ret; return ret;
} }
DEFINE_STATIC_CALL(amd_pstate_init_perf, pstate_init_perf); DEFINE_STATIC_CALL(amd_pstate_init_perf, msr_init_perf);
static inline int amd_pstate_init_perf(struct amd_cpudata *cpudata) static inline int amd_pstate_init_perf(struct amd_cpudata *cpudata)
{ {
return static_call(amd_pstate_init_perf)(cpudata); return static_call(amd_pstate_init_perf)(cpudata);
} }
static void cppc_update_perf(struct amd_cpudata *cpudata, static void shmem_update_perf(struct amd_cpudata *cpudata,
u32 min_perf, u32 des_perf, u32 min_perf, u32 des_perf,
u32 max_perf, bool fast_switch) u32 max_perf, bool fast_switch)
{ {
@ -527,9 +533,28 @@ cpufreq_policy_put:
cpufreq_cpu_put(policy); cpufreq_cpu_put(policy);
} }
static int amd_pstate_verify(struct cpufreq_policy_data *policy) static int amd_pstate_verify(struct cpufreq_policy_data *policy_data)
{ {
cpufreq_verify_within_cpu_limits(policy); /*
* Initialize lower frequency limit (i.e.policy->min) with
* lowest_nonlinear_frequency which is the most energy efficient
* frequency. Override the initial value set by cpufreq core and
* amd-pstate qos_requests.
*/
if (policy_data->min == FREQ_QOS_MIN_DEFAULT_VALUE) {
struct cpufreq_policy *policy = cpufreq_cpu_get(policy_data->cpu);
struct amd_cpudata *cpudata;
if (!policy)
return -EINVAL;
cpudata = policy->driver_data;
policy_data->min = cpudata->lowest_nonlinear_freq;
cpufreq_cpu_put(policy);
}
cpufreq_verify_within_cpu_limits(policy_data);
pr_debug("policy_max =%d, policy_min=%d\n", policy_data->max, policy_data->min);
return 0; return 0;
} }
@ -665,34 +690,12 @@ static void amd_pstate_adjust_perf(unsigned int cpu,
static int amd_pstate_cpu_boost_update(struct cpufreq_policy *policy, bool on) static int amd_pstate_cpu_boost_update(struct cpufreq_policy *policy, bool on)
{ {
struct amd_cpudata *cpudata = policy->driver_data; struct amd_cpudata *cpudata = policy->driver_data;
struct cppc_perf_ctrls perf_ctrls; u32 nominal_freq, max_freq;
u32 highest_perf, nominal_perf, nominal_freq, max_freq;
int ret = 0; int ret = 0;
highest_perf = READ_ONCE(cpudata->highest_perf);
nominal_perf = READ_ONCE(cpudata->nominal_perf);
nominal_freq = READ_ONCE(cpudata->nominal_freq); nominal_freq = READ_ONCE(cpudata->nominal_freq);
max_freq = READ_ONCE(cpudata->max_freq); max_freq = READ_ONCE(cpudata->max_freq);
if (boot_cpu_has(X86_FEATURE_CPPC)) {
u64 value = READ_ONCE(cpudata->cppc_req_cached);
value &= ~GENMASK_ULL(7, 0);
value |= on ? highest_perf : nominal_perf;
WRITE_ONCE(cpudata->cppc_req_cached, value);
wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value);
} else {
perf_ctrls.max_perf = on ? highest_perf : nominal_perf;
ret = cppc_set_perf(cpudata->cpu, &perf_ctrls);
if (ret) {
cpufreq_cpu_release(policy);
pr_debug("Failed to set max perf on CPU:%d. ret:%d\n",
cpudata->cpu, ret);
return ret;
}
}
if (on) if (on)
policy->cpuinfo.max_freq = max_freq; policy->cpuinfo.max_freq = max_freq;
else if (policy->cpuinfo.max_freq > nominal_freq * 1000) else if (policy->cpuinfo.max_freq > nominal_freq * 1000)
@ -1001,7 +1004,7 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
policy->fast_switch_possible = true; policy->fast_switch_possible = true;
ret = freq_qos_add_request(&policy->constraints, &cpudata->req[0], ret = freq_qos_add_request(&policy->constraints, &cpudata->req[0],
FREQ_QOS_MIN, policy->cpuinfo.min_freq); FREQ_QOS_MIN, FREQ_QOS_MIN_DEFAULT_VALUE);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "Failed to add min-freq constraint (%d)\n", ret); dev_err(dev, "Failed to add min-freq constraint (%d)\n", ret);
goto free_cpudata1; goto free_cpudata1;
@ -1045,7 +1048,7 @@ static int amd_pstate_cpu_resume(struct cpufreq_policy *policy)
{ {
int ret; int ret;
ret = amd_pstate_enable(true); ret = amd_pstate_cppc_enable(true);
if (ret) if (ret)
pr_err("failed to enable amd-pstate during resume, return %d\n", ret); pr_err("failed to enable amd-pstate during resume, return %d\n", ret);
@ -1056,7 +1059,7 @@ static int amd_pstate_cpu_suspend(struct cpufreq_policy *policy)
{ {
int ret; int ret;
ret = amd_pstate_enable(false); ret = amd_pstate_cppc_enable(false);
if (ret) if (ret)
pr_err("failed to disable amd-pstate during suspend, return %d\n", ret); pr_err("failed to disable amd-pstate during suspend, return %d\n", ret);
@ -1189,25 +1192,41 @@ static ssize_t show_energy_performance_preference(
static void amd_pstate_driver_cleanup(void) static void amd_pstate_driver_cleanup(void)
{ {
amd_pstate_enable(false); amd_pstate_cppc_enable(false);
cppc_state = AMD_PSTATE_DISABLE; cppc_state = AMD_PSTATE_DISABLE;
current_pstate_driver = NULL; current_pstate_driver = NULL;
} }
static int amd_pstate_set_driver(int mode_idx)
{
if (mode_idx >= AMD_PSTATE_DISABLE && mode_idx < AMD_PSTATE_MAX) {
cppc_state = mode_idx;
if (cppc_state == AMD_PSTATE_DISABLE)
pr_info("driver is explicitly disabled\n");
if (cppc_state == AMD_PSTATE_ACTIVE)
current_pstate_driver = &amd_pstate_epp_driver;
if (cppc_state == AMD_PSTATE_PASSIVE || cppc_state == AMD_PSTATE_GUIDED)
current_pstate_driver = &amd_pstate_driver;
return 0;
}
return -EINVAL;
}
static int amd_pstate_register_driver(int mode) static int amd_pstate_register_driver(int mode)
{ {
int ret; int ret;
if (mode == AMD_PSTATE_PASSIVE || mode == AMD_PSTATE_GUIDED) ret = amd_pstate_set_driver(mode);
current_pstate_driver = &amd_pstate_driver; if (ret)
else if (mode == AMD_PSTATE_ACTIVE) return ret;
current_pstate_driver = &amd_pstate_epp_driver;
else
return -EINVAL;
cppc_state = mode; cppc_state = mode;
ret = amd_pstate_enable(true); ret = amd_pstate_cppc_enable(true);
if (ret) { if (ret) {
pr_err("failed to enable cppc during amd-pstate driver registration, return %d\n", pr_err("failed to enable cppc during amd-pstate driver registration, return %d\n",
ret); ret);
@ -1485,6 +1504,8 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
WRITE_ONCE(cpudata->cppc_cap1_cached, value); WRITE_ONCE(cpudata->cppc_cap1_cached, value);
} }
current_pstate_driver->adjust_perf = NULL;
return 0; return 0;
free_cpudata1: free_cpudata1:
@ -1507,26 +1528,13 @@ static void amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy)
static int amd_pstate_epp_update_limit(struct cpufreq_policy *policy) static int amd_pstate_epp_update_limit(struct cpufreq_policy *policy)
{ {
struct amd_cpudata *cpudata = policy->driver_data; struct amd_cpudata *cpudata = policy->driver_data;
u32 max_perf, min_perf, min_limit_perf, max_limit_perf; u32 max_perf, min_perf;
u64 value; u64 value;
s16 epp; s16 epp;
if (cpudata->boost_supported && !policy->boost_enabled) max_perf = READ_ONCE(cpudata->highest_perf);
max_perf = READ_ONCE(cpudata->nominal_perf);
else
max_perf = READ_ONCE(cpudata->highest_perf);
min_perf = READ_ONCE(cpudata->lowest_perf); min_perf = READ_ONCE(cpudata->lowest_perf);
max_limit_perf = div_u64(policy->max * max_perf, policy->cpuinfo.max_freq); amd_pstate_update_min_max_limit(policy);
min_limit_perf = div_u64(policy->min * max_perf, policy->cpuinfo.max_freq);
if (min_limit_perf < min_perf)
min_limit_perf = min_perf;
if (max_limit_perf < min_limit_perf)
max_limit_perf = min_limit_perf;
WRITE_ONCE(cpudata->max_limit_perf, max_limit_perf);
WRITE_ONCE(cpudata->min_limit_perf, min_limit_perf);
max_perf = clamp_t(unsigned long, max_perf, cpudata->min_limit_perf, max_perf = clamp_t(unsigned long, max_perf, cpudata->min_limit_perf,
cpudata->max_limit_perf); cpudata->max_limit_perf);
@ -1535,7 +1543,7 @@ static int amd_pstate_epp_update_limit(struct cpufreq_policy *policy)
value = READ_ONCE(cpudata->cppc_req_cached); value = READ_ONCE(cpudata->cppc_req_cached);
if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE) if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE)
min_perf = max_perf; min_perf = min(cpudata->nominal_perf, max_perf);
/* Initial min/max values for CPPC Performance Controls Register */ /* Initial min/max values for CPPC Performance Controls Register */
value &= ~AMD_CPPC_MIN_PERF(~0L); value &= ~AMD_CPPC_MIN_PERF(~0L);
@ -1563,12 +1571,6 @@ static int amd_pstate_epp_update_limit(struct cpufreq_policy *policy)
if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE) if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE)
epp = 0; epp = 0;
/* Set initial EPP value */
if (cpu_feature_enabled(X86_FEATURE_CPPC)) {
value &= ~GENMASK_ULL(31, 24);
value |= (u64)epp << 24;
}
WRITE_ONCE(cpudata->cppc_req_cached, value); WRITE_ONCE(cpudata->cppc_req_cached, value);
return amd_pstate_set_epp(cpudata, epp); return amd_pstate_set_epp(cpudata, epp);
} }
@ -1605,7 +1607,7 @@ static void amd_pstate_epp_reenable(struct amd_cpudata *cpudata)
u64 value, max_perf; u64 value, max_perf;
int ret; int ret;
ret = amd_pstate_enable(true); ret = amd_pstate_cppc_enable(true);
if (ret) if (ret)
pr_err("failed to enable amd pstate during resume, return %d\n", ret); pr_err("failed to enable amd pstate during resume, return %d\n", ret);
@ -1616,8 +1618,9 @@ static void amd_pstate_epp_reenable(struct amd_cpudata *cpudata)
wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value); wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value);
} else { } else {
perf_ctrls.max_perf = max_perf; perf_ctrls.max_perf = max_perf;
perf_ctrls.energy_perf = AMD_CPPC_ENERGY_PERF_PREF(cpudata->epp_cached);
cppc_set_perf(cpudata->cpu, &perf_ctrls); cppc_set_perf(cpudata->cpu, &perf_ctrls);
perf_ctrls.energy_perf = AMD_CPPC_ENERGY_PERF_PREF(cpudata->epp_cached);
cppc_set_epp_perf(cpudata->cpu, &perf_ctrls, 1);
} }
} }
@ -1657,9 +1660,11 @@ static void amd_pstate_epp_offline(struct cpufreq_policy *policy)
wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value); wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value);
} else { } else {
perf_ctrls.desired_perf = 0; perf_ctrls.desired_perf = 0;
perf_ctrls.min_perf = min_perf;
perf_ctrls.max_perf = min_perf; perf_ctrls.max_perf = min_perf;
perf_ctrls.energy_perf = AMD_CPPC_ENERGY_PERF_PREF(HWP_EPP_BALANCE_POWERSAVE);
cppc_set_perf(cpudata->cpu, &perf_ctrls); cppc_set_perf(cpudata->cpu, &perf_ctrls);
perf_ctrls.energy_perf = AMD_CPPC_ENERGY_PERF_PREF(HWP_EPP_BALANCE_POWERSAVE);
cppc_set_epp_perf(cpudata->cpu, &perf_ctrls, 1);
} }
mutex_unlock(&amd_pstate_limits_lock); mutex_unlock(&amd_pstate_limits_lock);
} }
@ -1679,13 +1684,6 @@ static int amd_pstate_epp_cpu_offline(struct cpufreq_policy *policy)
return 0; return 0;
} }
static int amd_pstate_epp_verify_policy(struct cpufreq_policy_data *policy)
{
cpufreq_verify_within_cpu_limits(policy);
pr_debug("policy_max =%d, policy_min=%d\n", policy->max, policy->min);
return 0;
}
static int amd_pstate_epp_suspend(struct cpufreq_policy *policy) static int amd_pstate_epp_suspend(struct cpufreq_policy *policy)
{ {
struct amd_cpudata *cpudata = policy->driver_data; struct amd_cpudata *cpudata = policy->driver_data;
@ -1699,7 +1697,7 @@ static int amd_pstate_epp_suspend(struct cpufreq_policy *policy)
cpudata->suspended = true; cpudata->suspended = true;
/* disable CPPC in lowlevel firmware */ /* disable CPPC in lowlevel firmware */
ret = amd_pstate_enable(false); ret = amd_pstate_cppc_enable(false);
if (ret) if (ret)
pr_err("failed to suspend, return %d\n", ret); pr_err("failed to suspend, return %d\n", ret);
@ -1741,7 +1739,7 @@ static struct cpufreq_driver amd_pstate_driver = {
static struct cpufreq_driver amd_pstate_epp_driver = { static struct cpufreq_driver amd_pstate_epp_driver = {
.flags = CPUFREQ_CONST_LOOPS, .flags = CPUFREQ_CONST_LOOPS,
.verify = amd_pstate_epp_verify_policy, .verify = amd_pstate_verify,
.setpolicy = amd_pstate_epp_set_policy, .setpolicy = amd_pstate_epp_set_policy,
.init = amd_pstate_epp_cpu_init, .init = amd_pstate_epp_cpu_init,
.exit = amd_pstate_epp_cpu_exit, .exit = amd_pstate_epp_cpu_exit,
@ -1755,26 +1753,7 @@ static struct cpufreq_driver amd_pstate_epp_driver = {
.attr = amd_pstate_epp_attr, .attr = amd_pstate_epp_attr,
}; };
static int __init amd_pstate_set_driver(int mode_idx) /*
{
if (mode_idx >= AMD_PSTATE_DISABLE && mode_idx < AMD_PSTATE_MAX) {
cppc_state = mode_idx;
if (cppc_state == AMD_PSTATE_DISABLE)
pr_info("driver is explicitly disabled\n");
if (cppc_state == AMD_PSTATE_ACTIVE)
current_pstate_driver = &amd_pstate_epp_driver;
if (cppc_state == AMD_PSTATE_PASSIVE || cppc_state == AMD_PSTATE_GUIDED)
current_pstate_driver = &amd_pstate_driver;
return 0;
}
return -EINVAL;
}
/**
* CPPC function is not supported for family ID 17H with model_ID ranging from 0x10 to 0x2F. * CPPC function is not supported for family ID 17H with model_ID ranging from 0x10 to 0x2F.
* show the debug message that helps to check if the CPU has CPPC support for loading issue. * show the debug message that helps to check if the CPU has CPPC support for loading issue.
*/ */
@ -1864,10 +1843,10 @@ static int __init amd_pstate_init(void)
if (cppc_state == AMD_PSTATE_UNDEFINED) { if (cppc_state == AMD_PSTATE_UNDEFINED) {
/* Disable on the following configs by default: /* Disable on the following configs by default:
* 1. Undefined platforms * 1. Undefined platforms
* 2. Server platforms * 2. Server platforms with CPUs older than Family 0x1A.
*/ */
if (amd_pstate_acpi_pm_profile_undefined() || if (amd_pstate_acpi_pm_profile_undefined() ||
amd_pstate_acpi_pm_profile_server()) { (amd_pstate_acpi_pm_profile_server() && boot_cpu_data.x86 < 0x1A)) {
pr_info("driver load is disabled, boot with specific mode to enable this\n"); pr_info("driver load is disabled, boot with specific mode to enable this\n");
return -ENODEV; return -ENODEV;
} }
@ -1875,31 +1854,25 @@ static int __init amd_pstate_init(void)
cppc_state = CONFIG_X86_AMD_PSTATE_DEFAULT_MODE; cppc_state = CONFIG_X86_AMD_PSTATE_DEFAULT_MODE;
} }
switch (cppc_state) { if (cppc_state == AMD_PSTATE_DISABLE) {
case AMD_PSTATE_DISABLE:
pr_info("driver load is disabled, boot with specific mode to enable this\n"); pr_info("driver load is disabled, boot with specific mode to enable this\n");
return -ENODEV; return -ENODEV;
case AMD_PSTATE_PASSIVE:
case AMD_PSTATE_ACTIVE:
case AMD_PSTATE_GUIDED:
ret = amd_pstate_set_driver(cppc_state);
if (ret)
return ret;
break;
default:
return -EINVAL;
} }
/* capability check */ /* capability check */
if (cpu_feature_enabled(X86_FEATURE_CPPC)) { if (cpu_feature_enabled(X86_FEATURE_CPPC)) {
pr_debug("AMD CPPC MSR based functionality is supported\n"); pr_debug("AMD CPPC MSR based functionality is supported\n");
if (cppc_state != AMD_PSTATE_ACTIVE)
current_pstate_driver->adjust_perf = amd_pstate_adjust_perf;
} else { } else {
pr_debug("AMD CPPC shared memory based functionality is supported\n"); pr_debug("AMD CPPC shared memory based functionality is supported\n");
static_call_update(amd_pstate_enable, cppc_enable); static_call_update(amd_pstate_cppc_enable, shmem_cppc_enable);
static_call_update(amd_pstate_init_perf, cppc_init_perf); static_call_update(amd_pstate_init_perf, shmem_init_perf);
static_call_update(amd_pstate_update_perf, cppc_update_perf); static_call_update(amd_pstate_update_perf, shmem_update_perf);
}
ret = amd_pstate_register_driver(cppc_state);
if (ret) {
pr_err("failed to register with return %d\n", ret);
return ret;
} }
if (amd_pstate_prefcore) { if (amd_pstate_prefcore) {
@ -1908,19 +1881,6 @@ static int __init amd_pstate_init(void)
return ret; return ret;
} }
/* enable amd pstate feature */
ret = amd_pstate_enable(true);
if (ret) {
pr_err("failed to enable driver mode(%d)\n", cppc_state);
return ret;
}
ret = cpufreq_register_driver(current_pstate_driver);
if (ret) {
pr_err("failed to register with return %d\n", ret);
goto disable_driver;
}
dev_root = bus_get_dev_root(&cpu_subsys); dev_root = bus_get_dev_root(&cpu_subsys);
if (dev_root) { if (dev_root) {
ret = sysfs_create_group(&dev_root->kobj, &amd_pstate_global_attr_group); ret = sysfs_create_group(&dev_root->kobj, &amd_pstate_global_attr_group);
@ -1935,8 +1895,7 @@ static int __init amd_pstate_init(void)
global_attr_free: global_attr_free:
cpufreq_unregister_driver(current_pstate_driver); cpufreq_unregister_driver(current_pstate_driver);
disable_driver: amd_pstate_cppc_enable(false);
amd_pstate_enable(false);
return ret; return ret;
} }
device_initcall(amd_pstate_init); device_initcall(amd_pstate_init);

View File

@ -777,7 +777,7 @@ static struct platform_driver brcm_avs_cpufreq_platdrv = {
.of_match_table = brcm_avs_cpufreq_match, .of_match_table = brcm_avs_cpufreq_match,
}, },
.probe = brcm_avs_cpufreq_probe, .probe = brcm_avs_cpufreq_probe,
.remove_new = brcm_avs_cpufreq_remove, .remove = brcm_avs_cpufreq_remove,
}; };
module_platform_driver(brcm_avs_cpufreq_platdrv); module_platform_driver(brcm_avs_cpufreq_platdrv);

View File

@ -345,7 +345,7 @@ static struct platform_driver dt_cpufreq_platdrv = {
.name = "cpufreq-dt", .name = "cpufreq-dt",
}, },
.probe = dt_cpufreq_probe, .probe = dt_cpufreq_probe,
.remove_new = dt_cpufreq_remove, .remove = dt_cpufreq_remove,
}; };
module_platform_driver(dt_cpufreq_platdrv); module_platform_driver(dt_cpufreq_platdrv);

View File

@ -1520,7 +1520,7 @@ static int cpufreq_online(unsigned int cpu)
* frequency for longer duration. Hence, a BUG_ON(). * frequency for longer duration. Hence, a BUG_ON().
*/ */
BUG_ON(ret); BUG_ON(ret);
pr_info("%s: CPU%d: Running at unlisted initial frequency: %u KHz, changing to: %u KHz\n", pr_info("%s: CPU%d: Running at unlisted initial frequency: %u kHz, changing to: %u kHz\n",
__func__, policy->cpu, old_freq, policy->cur); __func__, policy->cpu, old_freq, policy->cur);
} }
} }

View File

@ -145,7 +145,7 @@ static struct platform_driver davinci_cpufreq_driver = {
.driver = { .driver = {
.name = "cpufreq-davinci", .name = "cpufreq-davinci",
}, },
.remove_new = __exit_p(davinci_cpufreq_remove), .remove = __exit_p(davinci_cpufreq_remove),
}; };
int __init davinci_cpufreq_init(void) int __init davinci_cpufreq_init(void)

View File

@ -183,7 +183,7 @@ static void imx_cpufreq_dt_remove(struct platform_device *pdev)
static struct platform_driver imx_cpufreq_dt_driver = { static struct platform_driver imx_cpufreq_dt_driver = {
.probe = imx_cpufreq_dt_probe, .probe = imx_cpufreq_dt_probe,
.remove_new = imx_cpufreq_dt_remove, .remove = imx_cpufreq_dt_remove,
.driver = { .driver = {
.name = "imx-cpufreq-dt", .name = "imx-cpufreq-dt",
}, },

View File

@ -522,7 +522,7 @@ static struct platform_driver imx6q_cpufreq_platdrv = {
.name = "imx6q-cpufreq", .name = "imx6q-cpufreq",
}, },
.probe = imx6q_cpufreq_probe, .probe = imx6q_cpufreq_probe,
.remove_new = imx6q_cpufreq_remove, .remove = imx6q_cpufreq_remove,
}; };
module_platform_driver(imx6q_cpufreq_platdrv); module_platform_driver(imx6q_cpufreq_platdrv);

View File

@ -3655,6 +3655,8 @@ static const struct x86_cpu_id intel_epp_default[] = {
X86_MATCH_VFM(INTEL_ALDERLAKE_L, HWP_SET_DEF_BALANCE_PERF_EPP(102)), X86_MATCH_VFM(INTEL_ALDERLAKE_L, HWP_SET_DEF_BALANCE_PERF_EPP(102)),
X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, HWP_SET_DEF_BALANCE_PERF_EPP(32)), X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, HWP_SET_DEF_BALANCE_PERF_EPP(32)),
X86_MATCH_VFM(INTEL_EMERALDRAPIDS_X, HWP_SET_DEF_BALANCE_PERF_EPP(32)), X86_MATCH_VFM(INTEL_EMERALDRAPIDS_X, HWP_SET_DEF_BALANCE_PERF_EPP(32)),
X86_MATCH_VFM(INTEL_GRANITERAPIDS_X, HWP_SET_DEF_BALANCE_PERF_EPP(32)),
X86_MATCH_VFM(INTEL_GRANITERAPIDS_D, HWP_SET_DEF_BALANCE_PERF_EPP(32)),
X86_MATCH_VFM(INTEL_METEORLAKE_L, HWP_SET_EPP_VALUES(HWP_EPP_POWERSAVE, X86_MATCH_VFM(INTEL_METEORLAKE_L, HWP_SET_EPP_VALUES(HWP_EPP_POWERSAVE,
179, 64, 16)), 179, 64, 16)),
X86_MATCH_VFM(INTEL_ARROWLAKE, HWP_SET_EPP_VALUES(HWP_EPP_POWERSAVE, X86_MATCH_VFM(INTEL_ARROWLAKE, HWP_SET_EPP_VALUES(HWP_EPP_POWERSAVE,

View File

@ -189,7 +189,7 @@ static void kirkwood_cpufreq_remove(struct platform_device *pdev)
static struct platform_driver kirkwood_cpufreq_platform_driver = { static struct platform_driver kirkwood_cpufreq_platform_driver = {
.probe = kirkwood_cpufreq_probe, .probe = kirkwood_cpufreq_probe,
.remove_new = kirkwood_cpufreq_remove, .remove = kirkwood_cpufreq_remove,
.driver = { .driver = {
.name = "kirkwood-cpufreq", .name = "kirkwood-cpufreq",
}, },

View File

@ -386,7 +386,7 @@ static struct platform_driver loongson3_platform_driver = {
}, },
.id_table = cpufreq_id_table, .id_table = cpufreq_id_table,
.probe = loongson3_cpufreq_probe, .probe = loongson3_cpufreq_probe,
.remove_new = loongson3_cpufreq_remove, .remove = loongson3_cpufreq_remove,
}; };
module_platform_driver(loongson3_platform_driver); module_platform_driver(loongson3_platform_driver);

View File

@ -344,7 +344,7 @@ MODULE_DEVICE_TABLE(of, mtk_cpufreq_hw_match);
static struct platform_driver mtk_cpufreq_hw_driver = { static struct platform_driver mtk_cpufreq_hw_driver = {
.probe = mtk_cpufreq_hw_driver_probe, .probe = mtk_cpufreq_hw_driver_probe,
.remove_new = mtk_cpufreq_hw_driver_remove, .remove = mtk_cpufreq_hw_driver_remove,
.driver = { .driver = {
.name = "mtk-cpufreq-hw", .name = "mtk-cpufreq-hw",
.of_match_table = mtk_cpufreq_hw_match, .of_match_table = mtk_cpufreq_hw_match,

View File

@ -188,7 +188,7 @@ static struct platform_driver omap_cpufreq_platdrv = {
.name = "omap-cpufreq", .name = "omap-cpufreq",
}, },
.probe = omap_cpufreq_probe, .probe = omap_cpufreq_probe,
.remove_new = omap_cpufreq_remove, .remove = omap_cpufreq_remove,
}; };
module_platform_driver(omap_cpufreq_platdrv); module_platform_driver(omap_cpufreq_platdrv);

View File

@ -615,7 +615,7 @@ static struct platform_driver pcc_cpufreq_platdrv = {
.driver = { .driver = {
.name = "pcc-cpufreq", .name = "pcc-cpufreq",
}, },
.remove_new = pcc_cpufreq_remove, .remove = pcc_cpufreq_remove,
}; };
static int __init pcc_cpufreq_init(void) static int __init pcc_cpufreq_init(void)

View File

@ -736,7 +736,7 @@ static void qcom_cpufreq_hw_driver_remove(struct platform_device *pdev)
static struct platform_driver qcom_cpufreq_hw_driver = { static struct platform_driver qcom_cpufreq_hw_driver = {
.probe = qcom_cpufreq_hw_driver_probe, .probe = qcom_cpufreq_hw_driver_probe,
.remove_new = qcom_cpufreq_hw_driver_remove, .remove = qcom_cpufreq_hw_driver_remove,
.driver = { .driver = {
.name = "qcom-cpufreq-hw", .name = "qcom-cpufreq-hw",
.of_match_table = qcom_cpufreq_hw_match, .of_match_table = qcom_cpufreq_hw_match,

View File

@ -604,7 +604,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(qcom_cpufreq_pm_ops, qcom_cpufreq_suspend, NULL)
static struct platform_driver qcom_cpufreq_driver = { static struct platform_driver qcom_cpufreq_driver = {
.probe = qcom_cpufreq_probe, .probe = qcom_cpufreq_probe,
.remove_new = qcom_cpufreq_remove, .remove = qcom_cpufreq_remove,
.driver = { .driver = {
.name = "qcom-cpufreq-nvmem", .name = "qcom-cpufreq-nvmem",
.pm = pm_sleep_ptr(&qcom_cpufreq_pm_ops), .pm = pm_sleep_ptr(&qcom_cpufreq_pm_ops),

View File

@ -296,7 +296,7 @@ static struct platform_driver qoriq_cpufreq_platform_driver = {
.name = "qoriq-cpufreq", .name = "qoriq-cpufreq",
}, },
.probe = qoriq_cpufreq_probe, .probe = qoriq_cpufreq_probe,
.remove_new = qoriq_cpufreq_remove, .remove = qoriq_cpufreq_remove,
}; };
module_platform_driver(qoriq_cpufreq_platform_driver); module_platform_driver(qoriq_cpufreq_platform_driver);

View File

@ -85,7 +85,7 @@ static struct platform_driver raspberrypi_cpufreq_driver = {
.name = "raspberrypi-cpufreq", .name = "raspberrypi-cpufreq",
}, },
.probe = raspberrypi_cpufreq_probe, .probe = raspberrypi_cpufreq_probe,
.remove_new = raspberrypi_cpufreq_remove, .remove = raspberrypi_cpufreq_remove,
}; };
module_platform_driver(raspberrypi_cpufreq_driver); module_platform_driver(raspberrypi_cpufreq_driver);

View File

@ -217,7 +217,7 @@ static struct platform_driver scpi_cpufreq_platdrv = {
.name = "scpi-cpufreq", .name = "scpi-cpufreq",
}, },
.probe = scpi_cpufreq_probe, .probe = scpi_cpufreq_probe,
.remove_new = scpi_cpufreq_remove, .remove = scpi_cpufreq_remove,
}; };
module_platform_driver(scpi_cpufreq_platdrv); module_platform_driver(scpi_cpufreq_platdrv);

View File

@ -283,7 +283,7 @@ static void sun50i_cpufreq_nvmem_remove(struct platform_device *pdev)
static struct platform_driver sun50i_cpufreq_driver = { static struct platform_driver sun50i_cpufreq_driver = {
.probe = sun50i_cpufreq_nvmem_probe, .probe = sun50i_cpufreq_nvmem_probe,
.remove_new = sun50i_cpufreq_nvmem_remove, .remove = sun50i_cpufreq_nvmem_remove,
.driver = { .driver = {
.name = "sun50i-cpufreq-nvmem", .name = "sun50i-cpufreq-nvmem",
}, },

View File

@ -276,7 +276,7 @@ static struct platform_driver tegra186_cpufreq_platform_driver = {
.of_match_table = tegra186_cpufreq_of_match, .of_match_table = tegra186_cpufreq_of_match,
}, },
.probe = tegra186_cpufreq_probe, .probe = tegra186_cpufreq_probe,
.remove_new = tegra186_cpufreq_remove, .remove = tegra186_cpufreq_remove,
}; };
module_platform_driver(tegra186_cpufreq_platform_driver); module_platform_driver(tegra186_cpufreq_platform_driver);

View File

@ -818,7 +818,7 @@ static struct platform_driver tegra194_ccplex_driver = {
.of_match_table = tegra194_cpufreq_of_match, .of_match_table = tegra194_cpufreq_of_match,
}, },
.probe = tegra194_cpufreq_probe, .probe = tegra194_cpufreq_probe,
.remove_new = tegra194_cpufreq_remove, .remove = tegra194_cpufreq_remove,
}; };
module_platform_driver(tegra194_ccplex_driver); module_platform_driver(tegra194_ccplex_driver);

View File

@ -565,7 +565,7 @@ static struct platform_driver ve_spc_cpufreq_platdrv = {
.name = "vexpress-spc-cpufreq", .name = "vexpress-spc-cpufreq",
}, },
.probe = ve_spc_cpufreq_probe, .probe = ve_spc_cpufreq_probe,
.remove_new = ve_spc_cpufreq_remove, .remove = ve_spc_cpufreq_remove,
}; };
module_platform_driver(ve_spc_cpufreq_platdrv); module_platform_driver(ve_spc_cpufreq_platdrv);

View File

@ -139,7 +139,7 @@ out_kfree_drv:
* *
* Initializes arm cpuidle driver for all CPUs, if any CPU fails * Initializes arm cpuidle driver for all CPUs, if any CPU fails
* to register cpuidle driver then rollback to cancel all CPUs * to register cpuidle driver then rollback to cancel all CPUs
* registeration. * registration.
*/ */
static int __init arm_idle_init(void) static int __init arm_idle_init(void)
{ {

View File

@ -48,7 +48,7 @@ static int qcom_cpu_spc(struct spm_driver_data *drv)
ret = cpu_suspend(0, qcom_pm_collapse); ret = cpu_suspend(0, qcom_pm_collapse);
/* /*
* ARM common code executes WFI without calling into our driver and * ARM common code executes WFI without calling into our driver and
* if the SPM mode is not reset, then we may accidently power down the * if the SPM mode is not reset, then we may accidentally power down the
* cpu when we intended only to gate the cpu clock. * cpu when we intended only to gate the cpu clock.
* Ensure the state is set to standby before returning. * Ensure the state is set to standby before returning.
*/ */

View File

@ -406,7 +406,7 @@ void cpuidle_reflect(struct cpuidle_device *dev, int index)
* Min polling interval of 10usec is a guess. It is assuming that * Min polling interval of 10usec is a guess. It is assuming that
* for most users, the time for a single ping-pong workload like * for most users, the time for a single ping-pong workload like
* perf bench pipe would generally complete within 10usec but * perf bench pipe would generally complete within 10usec but
* this is hardware dependant. Actual time can be estimated with * this is hardware dependent. Actual time can be estimated with
* *
* perf bench sched pipe -l 10000 * perf bench sched pipe -l 10000
* *

View File

@ -261,7 +261,7 @@ static void __cpuidle_unregister_driver(struct cpuidle_driver *drv)
* @drv: a pointer to a valid struct cpuidle_driver * @drv: a pointer to a valid struct cpuidle_driver
* *
* Register the driver under a lock to prevent concurrent attempts to * Register the driver under a lock to prevent concurrent attempts to
* [un]register the driver from occuring at the same time. * [un]register the driver from occurring at the same time.
* *
* Returns 0 on success, a negative error code (returned by * Returns 0 on success, a negative error code (returned by
* __cpuidle_register_driver()) otherwise. * __cpuidle_register_driver()) otherwise.
@ -296,7 +296,7 @@ EXPORT_SYMBOL_GPL(cpuidle_register_driver);
* @drv: a pointer to a valid struct cpuidle_driver * @drv: a pointer to a valid struct cpuidle_driver
* *
* Unregisters the cpuidle driver under a lock to prevent concurrent attempts * Unregisters the cpuidle driver under a lock to prevent concurrent attempts
* to [un]register the driver from occuring at the same time. @drv has to * to [un]register the driver from occurring at the same time. @drv has to
* match the currently registered driver. * match the currently registered driver.
*/ */
void cpuidle_unregister_driver(struct cpuidle_driver *drv) void cpuidle_unregister_driver(struct cpuidle_driver *drv)

View File

@ -19,7 +19,7 @@
#include "gov.h" #include "gov.h"
#define BUCKETS 12 #define BUCKETS 6
#define INTERVAL_SHIFT 3 #define INTERVAL_SHIFT 3
#define INTERVALS (1UL << INTERVAL_SHIFT) #define INTERVALS (1UL << INTERVAL_SHIFT)
#define RESOLUTION 1024 #define RESOLUTION 1024
@ -29,12 +29,11 @@
/* /*
* Concepts and ideas behind the menu governor * Concepts and ideas behind the menu governor
* *
* For the menu governor, there are 3 decision factors for picking a C * For the menu governor, there are 2 decision factors for picking a C
* state: * state:
* 1) Energy break even point * 1) Energy break even point
* 2) Performance impact * 2) Latency tolerance (from pmqos infrastructure)
* 3) Latency tolerance (from pmqos infrastructure) * These two factors are treated independently.
* These three factors are treated independently.
* *
* Energy break even point * Energy break even point
* ----------------------- * -----------------------
@ -75,30 +74,6 @@
* intervals and if the stand deviation of these 8 intervals is below a * intervals and if the stand deviation of these 8 intervals is below a
* threshold value, we use the average of these intervals as prediction. * threshold value, we use the average of these intervals as prediction.
* *
* Limiting Performance Impact
* ---------------------------
* C states, especially those with large exit latencies, can have a real
* noticeable impact on workloads, which is not acceptable for most sysadmins,
* and in addition, less performance has a power price of its own.
*
* As a general rule of thumb, menu assumes that the following heuristic
* holds:
* The busier the system, the less impact of C states is acceptable
*
* This rule-of-thumb is implemented using a performance-multiplier:
* If the exit latency times the performance multiplier is longer than
* the predicted duration, the C state is not considered a candidate
* for selection due to a too high performance impact. So the higher
* this multiplier is, the longer we need to be idle to pick a deep C
* state, and thus the less likely a busy CPU will hit such a deep
* C state.
*
* Currently there is only one value determining the factor:
* 10 points are added for each process that is waiting for IO on this CPU.
* (This value was experimentally determined.)
* Utilization is no longer a factor as it was shown that it never contributed
* significantly to the performance multiplier in the first place.
*
*/ */
struct menu_device { struct menu_device {
@ -112,19 +87,10 @@ struct menu_device {
int interval_ptr; int interval_ptr;
}; };
static inline int which_bucket(u64 duration_ns, unsigned int nr_iowaiters) static inline int which_bucket(u64 duration_ns)
{ {
int bucket = 0; int bucket = 0;
/*
* We keep two groups of stats; one with no
* IO pending, one without.
* This allows us to calculate
* E(duration)|iowait
*/
if (nr_iowaiters)
bucket = BUCKETS/2;
if (duration_ns < 10ULL * NSEC_PER_USEC) if (duration_ns < 10ULL * NSEC_PER_USEC)
return bucket; return bucket;
if (duration_ns < 100ULL * NSEC_PER_USEC) if (duration_ns < 100ULL * NSEC_PER_USEC)
@ -138,19 +104,6 @@ static inline int which_bucket(u64 duration_ns, unsigned int nr_iowaiters)
return bucket + 5; return bucket + 5;
} }
/*
* Return a multiplier for the exit latency that is intended
* to take performance requirements into account.
* The more performance critical we estimate the system
* to be, the higher this multiplier, and thus the higher
* the barrier to go to an expensive C state.
*/
static inline int performance_multiplier(unsigned int nr_iowaiters)
{
/* for IO wait tasks (per cpu!) we add 10x each */
return 1 + 10 * nr_iowaiters;
}
static DEFINE_PER_CPU(struct menu_device, menu_devices); static DEFINE_PER_CPU(struct menu_device, menu_devices);
static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev); static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev);
@ -258,8 +211,6 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
struct menu_device *data = this_cpu_ptr(&menu_devices); struct menu_device *data = this_cpu_ptr(&menu_devices);
s64 latency_req = cpuidle_governor_latency_req(dev->cpu); s64 latency_req = cpuidle_governor_latency_req(dev->cpu);
u64 predicted_ns; u64 predicted_ns;
u64 interactivity_req;
unsigned int nr_iowaiters;
ktime_t delta, delta_tick; ktime_t delta, delta_tick;
int i, idx; int i, idx;
@ -268,8 +219,6 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
data->needs_update = 0; data->needs_update = 0;
} }
nr_iowaiters = nr_iowait_cpu(dev->cpu);
/* Find the shortest expected idle interval. */ /* Find the shortest expected idle interval. */
predicted_ns = get_typical_interval(data) * NSEC_PER_USEC; predicted_ns = get_typical_interval(data) * NSEC_PER_USEC;
if (predicted_ns > RESIDENCY_THRESHOLD_NS) { if (predicted_ns > RESIDENCY_THRESHOLD_NS) {
@ -283,7 +232,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
} }
data->next_timer_ns = delta; data->next_timer_ns = delta;
data->bucket = which_bucket(data->next_timer_ns, nr_iowaiters); data->bucket = which_bucket(data->next_timer_ns);
/* Round up the result for half microseconds. */ /* Round up the result for half microseconds. */
timer_us = div_u64((RESOLUTION * DECAY * NSEC_PER_USEC) / 2 + timer_us = div_u64((RESOLUTION * DECAY * NSEC_PER_USEC) / 2 +
@ -301,7 +250,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
*/ */
data->next_timer_ns = KTIME_MAX; data->next_timer_ns = KTIME_MAX;
delta_tick = TICK_NSEC / 2; delta_tick = TICK_NSEC / 2;
data->bucket = which_bucket(KTIME_MAX, nr_iowaiters); data->bucket = which_bucket(KTIME_MAX);
} }
if (unlikely(drv->state_count <= 1 || latency_req == 0) || if (unlikely(drv->state_count <= 1 || latency_req == 0) ||
@ -328,15 +277,8 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
*/ */
if (predicted_ns < TICK_NSEC) if (predicted_ns < TICK_NSEC)
predicted_ns = data->next_timer_ns; predicted_ns = data->next_timer_ns;
} else { } else if (latency_req > predicted_ns) {
/* latency_req = predicted_ns;
* Use the performance multiplier and the user-configurable
* latency_req to determine the maximum exit latency.
*/
interactivity_req = div64_u64(predicted_ns,
performance_multiplier(nr_iowaiters));
if (latency_req > interactivity_req)
latency_req = interactivity_req;
} }
/* /*

View File

@ -1069,6 +1069,47 @@ static struct cpuidle_state gnr_cstates[] __initdata = {
.enter = NULL } .enter = NULL }
}; };
static struct cpuidle_state gnrd_cstates[] __initdata = {
{
.name = "C1",
.desc = "MWAIT 0x00",
.flags = MWAIT2flg(0x00),
.exit_latency = 1,
.target_residency = 1,
.enter = &intel_idle,
.enter_s2idle = intel_idle_s2idle, },
{
.name = "C1E",
.desc = "MWAIT 0x01",
.flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE,
.exit_latency = 4,
.target_residency = 4,
.enter = &intel_idle,
.enter_s2idle = intel_idle_s2idle, },
{
.name = "C6",
.desc = "MWAIT 0x20",
.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED |
CPUIDLE_FLAG_INIT_XSTATE |
CPUIDLE_FLAG_PARTIAL_HINT_MATCH,
.exit_latency = 220,
.target_residency = 650,
.enter = &intel_idle,
.enter_s2idle = intel_idle_s2idle, },
{
.name = "C6P",
.desc = "MWAIT 0x21",
.flags = MWAIT2flg(0x21) | CPUIDLE_FLAG_TLB_FLUSHED |
CPUIDLE_FLAG_INIT_XSTATE |
CPUIDLE_FLAG_PARTIAL_HINT_MATCH,
.exit_latency = 240,
.target_residency = 750,
.enter = &intel_idle,
.enter_s2idle = intel_idle_s2idle, },
{
.enter = NULL }
};
static struct cpuidle_state atom_cstates[] __initdata = { static struct cpuidle_state atom_cstates[] __initdata = {
{ {
.name = "C1E", .name = "C1E",
@ -1508,6 +1549,12 @@ static const struct idle_cpu idle_cpu_gnr __initconst = {
.use_acpi = true, .use_acpi = true,
}; };
static const struct idle_cpu idle_cpu_gnrd __initconst = {
.state_table = gnrd_cstates,
.disable_promotion_to_c1e = true,
.use_acpi = true,
};
static const struct idle_cpu idle_cpu_avn __initconst = { static const struct idle_cpu idle_cpu_avn __initconst = {
.state_table = avn_cstates, .state_table = avn_cstates,
.disable_promotion_to_c1e = true, .disable_promotion_to_c1e = true,
@ -1593,6 +1640,7 @@ static const struct x86_cpu_id intel_idle_ids[] __initconst = {
X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, &idle_cpu_spr), X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, &idle_cpu_spr),
X86_MATCH_VFM(INTEL_EMERALDRAPIDS_X, &idle_cpu_spr), X86_MATCH_VFM(INTEL_EMERALDRAPIDS_X, &idle_cpu_spr),
X86_MATCH_VFM(INTEL_GRANITERAPIDS_X, &idle_cpu_gnr), X86_MATCH_VFM(INTEL_GRANITERAPIDS_X, &idle_cpu_gnr),
X86_MATCH_VFM(INTEL_GRANITERAPIDS_D, &idle_cpu_gnrd),
X86_MATCH_VFM(INTEL_XEON_PHI_KNL, &idle_cpu_knl), X86_MATCH_VFM(INTEL_XEON_PHI_KNL, &idle_cpu_knl),
X86_MATCH_VFM(INTEL_XEON_PHI_KNM, &idle_cpu_knl), X86_MATCH_VFM(INTEL_XEON_PHI_KNM, &idle_cpu_knl),
X86_MATCH_VFM(INTEL_ATOM_GOLDMONT, &idle_cpu_bxt), X86_MATCH_VFM(INTEL_ATOM_GOLDMONT, &idle_cpu_bxt),

View File

@ -55,6 +55,8 @@ struct em_perf_table {
* struct em_perf_domain - Performance domain * struct em_perf_domain - Performance domain
* @em_table: Pointer to the runtime modifiable em_perf_table * @em_table: Pointer to the runtime modifiable em_perf_table
* @nr_perf_states: Number of performance states * @nr_perf_states: Number of performance states
* @min_perf_state: Minimum allowed Performance State index
* @max_perf_state: Maximum allowed Performance State index
* @flags: See "em_perf_domain flags" * @flags: See "em_perf_domain flags"
* @cpus: Cpumask covering the CPUs of the domain. It's here * @cpus: Cpumask covering the CPUs of the domain. It's here
* for performance reasons to avoid potential cache * for performance reasons to avoid potential cache
@ -70,6 +72,8 @@ struct em_perf_table {
struct em_perf_domain { struct em_perf_domain {
struct em_perf_table __rcu *em_table; struct em_perf_table __rcu *em_table;
int nr_perf_states; int nr_perf_states;
int min_perf_state;
int max_perf_state;
unsigned long flags; unsigned long flags;
unsigned long cpus[]; unsigned long cpus[];
}; };
@ -173,13 +177,14 @@ void em_table_free(struct em_perf_table __rcu *table);
int em_dev_compute_costs(struct device *dev, struct em_perf_state *table, int em_dev_compute_costs(struct device *dev, struct em_perf_state *table,
int nr_states); int nr_states);
int em_dev_update_chip_binning(struct device *dev); int em_dev_update_chip_binning(struct device *dev);
int em_update_performance_limits(struct em_perf_domain *pd,
unsigned long freq_min_khz, unsigned long freq_max_khz);
/** /**
* em_pd_get_efficient_state() - Get an efficient performance state from the EM * em_pd_get_efficient_state() - Get an efficient performance state from the EM
* @table: List of performance states, in ascending order * @table: List of performance states, in ascending order
* @nr_perf_states: Number of performance states * @pd: performance domain for which this must be done
* @max_util: Max utilization to map with the EM * @max_util: Max utilization to map with the EM
* @pd_flags: Performance Domain flags
* *
* It is called from the scheduler code quite frequently and as a consequence * It is called from the scheduler code quite frequently and as a consequence
* doesn't implement any check. * doesn't implement any check.
@ -188,13 +193,16 @@ int em_dev_update_chip_binning(struct device *dev);
* requirement. * requirement.
*/ */
static inline int static inline int
em_pd_get_efficient_state(struct em_perf_state *table, int nr_perf_states, em_pd_get_efficient_state(struct em_perf_state *table,
unsigned long max_util, unsigned long pd_flags) struct em_perf_domain *pd, unsigned long max_util)
{ {
unsigned long pd_flags = pd->flags;
int min_ps = pd->min_perf_state;
int max_ps = pd->max_perf_state;
struct em_perf_state *ps; struct em_perf_state *ps;
int i; int i;
for (i = 0; i < nr_perf_states; i++) { for (i = min_ps; i <= max_ps; i++) {
ps = &table[i]; ps = &table[i];
if (ps->performance >= max_util) { if (ps->performance >= max_util) {
if (pd_flags & EM_PERF_DOMAIN_SKIP_INEFFICIENCIES && if (pd_flags & EM_PERF_DOMAIN_SKIP_INEFFICIENCIES &&
@ -204,7 +212,7 @@ em_pd_get_efficient_state(struct em_perf_state *table, int nr_perf_states,
} }
} }
return nr_perf_states - 1; return max_ps;
} }
/** /**
@ -253,8 +261,7 @@ static inline unsigned long em_cpu_energy(struct em_perf_domain *pd,
* requested performance. * requested performance.
*/ */
em_table = rcu_dereference(pd->em_table); em_table = rcu_dereference(pd->em_table);
i = em_pd_get_efficient_state(em_table->state, pd->nr_perf_states, i = em_pd_get_efficient_state(em_table->state, pd, max_util);
max_util, pd->flags);
ps = &em_table->state[i]; ps = &em_table->state[i];
/* /*
@ -391,6 +398,12 @@ static inline int em_dev_update_chip_binning(struct device *dev)
{ {
return -EINVAL; return -EINVAL;
} }
static inline
int em_update_performance_limits(struct em_perf_domain *pd,
unsigned long freq_min_khz, unsigned long freq_max_khz)
{
return -EINVAL;
}
#endif #endif
#endif #endif

View File

@ -628,6 +628,8 @@ int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states,
goto unlock; goto unlock;
dev->em_pd->flags |= flags; dev->em_pd->flags |= flags;
dev->em_pd->min_perf_state = 0;
dev->em_pd->max_perf_state = nr_states - 1;
em_cpufreq_update_efficiencies(dev, dev->em_pd->em_table->state); em_cpufreq_update_efficiencies(dev, dev->em_pd->em_table->state);
@ -856,3 +858,53 @@ int em_dev_update_chip_binning(struct device *dev)
return em_recalc_and_update(dev, pd, em_table); return em_recalc_and_update(dev, pd, em_table);
} }
EXPORT_SYMBOL_GPL(em_dev_update_chip_binning); EXPORT_SYMBOL_GPL(em_dev_update_chip_binning);
/**
* em_update_performance_limits() - Update Energy Model with performance
* limits information.
* @pd : Performance Domain with EM that has to be updated.
* @freq_min_khz : New minimum allowed frequency for this device.
* @freq_max_khz : New maximum allowed frequency for this device.
*
* This function allows to update the EM with information about available
* performance levels. It takes the minimum and maximum frequency in kHz
* and does internal translation to performance levels.
* Returns 0 on success or -EINVAL when failed.
*/
int em_update_performance_limits(struct em_perf_domain *pd,
unsigned long freq_min_khz, unsigned long freq_max_khz)
{
struct em_perf_state *table;
int min_ps = -1;
int max_ps = -1;
int i;
if (!pd)
return -EINVAL;
rcu_read_lock();
table = em_perf_state_from_pd(pd);
for (i = 0; i < pd->nr_perf_states; i++) {
if (freq_min_khz == table[i].frequency)
min_ps = i;
if (freq_max_khz == table[i].frequency)
max_ps = i;
}
rcu_read_unlock();
/* Only update when both are found and sane */
if (min_ps < 0 || max_ps < 0 || max_ps < min_ps)
return -EINVAL;
/* Guard simultaneous updates and make them atomic */
mutex_lock(&em_pd_mutex);
pd->min_perf_state = min_ps;
pd->max_perf_state = max_ps;
mutex_unlock(&em_pd_mutex);
return 0;
}
EXPORT_SYMBOL_GPL(em_update_performance_limits);

View File

@ -783,9 +783,8 @@ static int sugov_init(struct cpufreq_policy *policy)
if (ret) if (ret)
goto fail; goto fail;
sugov_eas_rebuild_sd();
out: out:
sugov_eas_rebuild_sd();
mutex_unlock(&global_tunables_lock); mutex_unlock(&global_tunables_lock);
return 0; return 0;

View File

@ -27,3 +27,6 @@ debug/i386/intel_gsic
debug/i386/powernow-k8-decode debug/i386/powernow-k8-decode
debug/x86_64/centrino-decode debug/x86_64/centrino-decode
debug/x86_64/powernow-k8-decode debug/x86_64/powernow-k8-decode
# Clang's compilation database file
compile_commands.json

View File

@ -57,7 +57,7 @@ LIB_MIN= 1
PACKAGE = cpupower PACKAGE = cpupower
PACKAGE_BUGREPORT = linux-pm@vger.kernel.org PACKAGE_BUGREPORT = linux-pm@vger.kernel.org
LANGUAGES = de fr it cs pt ka LANGUAGES = de fr it cs pt ka zh_CN
# Directory definitions. These are default and most probably # Directory definitions. These are default and most probably
@ -86,12 +86,12 @@ INSTALL_SCRIPT = ${INSTALL} -m 644
# If you are running a cross compiler, you may want to set this # If you are running a cross compiler, you may want to set this
# to something more interesting, like "arm-linux-". If you want # to something more interesting, like "arm-linux-". If you want
# to compile vs uClibc, that can be done here as well. # to compile vs uClibc, that can be done here as well.
CROSS = #/usr/i386-linux-uclibc/usr/bin/i386-uclibc- CROSS ?= #/usr/i386-linux-uclibc/usr/bin/i386-uclibc-
CC = $(CROSS)gcc CC ?= $(CROSS)gcc
LD = $(CROSS)gcc LD ?= $(CROSS)gcc
AR = $(CROSS)ar AR ?= $(CROSS)ar
STRIP = $(CROSS)strip STRIP ?= $(CROSS)strip
RANLIB = $(CROSS)ranlib RANLIB ?= $(CROSS)ranlib
HOSTCC = gcc HOSTCC = gcc
MKDIR = mkdir MKDIR = mkdir
@ -218,17 +218,28 @@ else
endif endif
$(QUIET) $(STRIPCMD) $@ $(QUIET) $(STRIPCMD) $@
ifeq (, $(shell which xgettext))
$(warning "Install xgettext to extract translatable strings.")
else
$(OUTPUT)po/$(PACKAGE).pot: $(UTIL_SRC) $(OUTPUT)po/$(PACKAGE).pot: $(UTIL_SRC)
$(ECHO) " GETTEXT " $@ $(ECHO) " GETTEXT " $@
$(QUIET) xgettext --default-domain=$(PACKAGE) --add-comments \ $(QUIET) xgettext --default-domain=$(PACKAGE) --add-comments \
--keyword=_ --keyword=N_ $(UTIL_SRC) -p $(@D) -o $(@F) --keyword=_ --keyword=N_ $(UTIL_SRC) -p $(@D) -o $(@F)
endif
ifeq (, $(shell which msgfmt))
$(warning "Install msgfmt to generate binary message catalogs.")
else
$(OUTPUT)po/%.gmo: po/%.po $(OUTPUT)po/%.gmo: po/%.po
$(ECHO) " MSGFMT " $@ $(ECHO) " MSGFMT " $@
$(QUIET) msgfmt -o $@ po/$*.po $(QUIET) msgfmt -o $@ po/$*.po
endif
create-gmo: ${GMO_FILES} create-gmo: ${GMO_FILES}
ifeq (, $(shell which msgmerge))
$(warning "Install msgmerge to merge translations.")
else
update-po: $(OUTPUT)po/$(PACKAGE).pot update-po: $(OUTPUT)po/$(PACKAGE).pot
$(ECHO) " MSGMRG " $@ $(ECHO) " MSGMRG " $@
$(QUIET) @for HLANG in $(LANGUAGES); do \ $(QUIET) @for HLANG in $(LANGUAGES); do \
@ -241,6 +252,7 @@ update-po: $(OUTPUT)po/$(PACKAGE).pot
rm -f $(OUTPUT)po/$$HLANG.new.po; \ rm -f $(OUTPUT)po/$$HLANG.new.po; \
fi; \ fi; \
done; done;
endif
compile-bench: $(OUTPUT)libcpupower.so.$(LIB_MAJ) compile-bench: $(OUTPUT)libcpupower.so.$(LIB_MAJ)
@V=$(V) confdir=$(confdir) $(MAKE) -C bench O=$(OUTPUT) @V=$(V) confdir=$(confdir) $(MAKE) -C bench O=$(OUTPUT)

View File

@ -4,6 +4,7 @@
* Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de> * Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de>
*/ */
#include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
@ -165,8 +166,8 @@ int prepare_config(const char *path, struct config *config)
configfile = fopen(path, "r"); configfile = fopen(path, "r");
if (configfile == NULL) { if (configfile == NULL) {
perror("fopen"); fprintf(stderr, "error: unable to read configfile: %s, %s\n",
fprintf(stderr, "error: unable to read configfile\n"); path, strerror(errno));
free(config); free(config);
return 1; return 1;
} }

View File

@ -15,22 +15,38 @@ else:
print(f"cstate count error: return code: {cpu_cstates_count}") print(f"cstate count error: return code: {cpu_cstates_count}")
""" """
Disable cstate (will fail if the above is 0, ex: a virtual machine) Disable cstate (will fail if the above returns is under 1, ex: a virtual machine)
""" """
cstate_disabled = p.cpuidle_state_disable(0, 0, 1) cstate_disabled = p.cpuidle_state_disable(0, 0, 1)
if cpu_cstates_count == 0:
print(f"CPU 0 has {cpu_cstates_count} c-states")
else:
print(f"cstate count error: return code: {cpu_cstates_count}")
match cstate_disabled: match cstate_disabled:
case 0: case 0:
print(f"CPU state disabled") print(f"CPU state disabled")
case -1: case -1:
print(f"Idlestate not available") print(f"Idlestate not available")
case -2:
print(f"Disabling is not supported by the kernel")
case -3:
print(f"No write access to disable/enable C-states: try using sudo")
case _: case _:
print(f"Not documented") print(f"Not documented: {cstate_disabled}")
"""
Test cstate is disabled
"""
is_cstate_disabled = p.cpuidle_is_state_disabled(0, 0)
match is_cstate_disabled:
case 1:
print(f"CPU is disabled")
case 0:
print(f"CPU is enabled")
case -1:
print(f"Idlestate not available")
case -2:
print(f"Disabling is not supported by kernel")
case _:
print(f"Not documented: {is_cstate_disabled}")
# Pointer example # Pointer example

View File

@ -3,7 +3,7 @@
cpupower\-set \- Set processor power related kernel or hardware configurations cpupower\-set \- Set processor power related kernel or hardware configurations
.SH SYNOPSIS .SH SYNOPSIS
.ft B .ft B
.B cpupower set [ \-b VAL ] .B cpupower set [ \-b VAL | \-e POLICY | \-m MODE | \-t BOOL ]
.SH DESCRIPTION .SH DESCRIPTION
@ -19,7 +19,7 @@ described in the Options sections.
Use \fBcpupower info \fP to read out current settings and whether they are Use \fBcpupower info \fP to read out current settings and whether they are
supported on the system at all. supported on the system at all.
.SH Options .SH OPTIONS
.PP .PP
\-\-perf-bias, \-b \-\-perf-bias, \-b
.RS 4 .RS 4
@ -56,6 +56,40 @@ Use \fBcpupower -c all info -b\fP to verify.
This options needs the msr kernel driver (CONFIG_X86_MSR) loaded. This options needs the msr kernel driver (CONFIG_X86_MSR) loaded.
.RE .RE
.PP
\-\-epp, \-e
.RS 4
Sets the energy performance policy preference on supported Intel or AMD
processors which use the Intel or AMD P-State cpufreq driver respectively.
Available policies can be found with
\fBcat /sys/devices/system/cpu/cpufreq/policy0/energy_performance_available_preferences\fP :
.RS 4
default performance balance_performance balance_power power
.RE
.RE
.PP
\-\-amd\-pstate\-mode, \-m
.RS 4
Sets the AMD P-State mode for supported AMD processors.
Available modes are "active", "guided" or "passive".
Refer to the AMD P-State kernel documentation for further information.
.RE
.PP
\-\-turbo\-boost, \-t
.RS 4
This option is used to enable or disable the turbo boost feature on
supported Intel and AMD processors.
This option takes as parameter either \fB1\fP to enable, or \fB0\fP to disable the feature.
.RE
.SH "SEE ALSO" .SH "SEE ALSO"
cpupower-info(1), cpupower-monitor(1), powertop(1) cpupower-info(1), cpupower-monitor(1), powertop(1)
.PP .PP

View File

@ -0,0 +1,942 @@
# Chinese Simplified translations for cpufrequtils package
# Copyright (C) 2004 THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the cpufrequtils package.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: cpufrequtils 006\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-03-08 17:03+0100\n"
"PO-Revision-Date: 2024-05-22 15:36+0000\n"
"Last-Translator: Kieran Moy <kfatyuip@gmail.com>\n"
"Language-Team: NONE\n"
"Language: zh_CN\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 3.4.2\n"
#: utils/idle_monitor/nhm_idle.c:36
msgid "Processor Core C3"
msgstr "处理器 Core C3"
#: utils/idle_monitor/nhm_idle.c:43
msgid "Processor Core C6"
msgstr "处理器 Core C6"
#: utils/idle_monitor/nhm_idle.c:51
msgid "Processor Package C3"
msgstr "处理器套件 C3"
#: utils/idle_monitor/nhm_idle.c:58 utils/idle_monitor/amd_fam14h_idle.c:70
msgid "Processor Package C6"
msgstr "处理器套件 C6"
#: utils/idle_monitor/snb_idle.c:33
msgid "Processor Core C7"
msgstr "处理器 Core C7"
#: utils/idle_monitor/snb_idle.c:40
msgid "Processor Package C2"
msgstr "处理器套件 C2"
#: utils/idle_monitor/snb_idle.c:47
msgid "Processor Package C7"
msgstr "处理器套件 C7"
#: utils/idle_monitor/amd_fam14h_idle.c:56
msgid "Package in sleep state (PC1 or deeper)"
msgstr "Package in sleep state PC1 或更深)"
#: utils/idle_monitor/amd_fam14h_idle.c:63
msgid "Processor Package C1"
msgstr "处理器套件 C1"
#: utils/idle_monitor/amd_fam14h_idle.c:77
msgid "North Bridge P1 boolean counter (returns 0 or 1)"
msgstr "北桥 P1 布尔计数器(返回 0 或 1"
#: utils/idle_monitor/mperf_monitor.c:35
msgid "Processor Core not idle"
msgstr "处理器 Core不空闲"
#: utils/idle_monitor/mperf_monitor.c:42
msgid "Processor Core in an idle state"
msgstr "处理器 Core处于空闲状态"
#: utils/idle_monitor/mperf_monitor.c:50
msgid "Average Frequency (including boost) in MHz"
msgstr "平均频率(包括增加频率),单位 MHz"
#: utils/idle_monitor/cpupower-monitor.c:66
#, c-format
msgid ""
"cpupower monitor: [-h] [ [-t] | [-l] | [-m <mon1>,[<mon2>] ] ] [-i "
"interval_sec | -c command ...]\n"
msgstr ""
"cpupower monitor[-h] [ [-t] | [-l] | [-m <mon1>,[<mon2>] ] ] [-i "
"interval_sec | -c command...]\n"
#: utils/idle_monitor/cpupower-monitor.c:69
#, c-format
msgid ""
"cpupower monitor: [-v] [-h] [ [-t] | [-l] | [-m <mon1>,[<mon2>] ] ] [-i "
"interval_sec | -c command ...]\n"
msgstr ""
"cpupower monitor[-v] [-h] [ [-t] | [-l] | [-m <mon1>,[<mon2>] ] ] [-i "
"interval_sec | -c command...]\n"
#: utils/idle_monitor/cpupower-monitor.c:71
#, c-format
msgid "\t -v: be more verbose\n"
msgstr "-v更详细\n"
#: utils/idle_monitor/cpupower-monitor.c:73
#, c-format
msgid "\t -h: print this help\n"
msgstr "-h打印此帮助\n"
#: utils/idle_monitor/cpupower-monitor.c:74
#, c-format
msgid "\t -i: time interval to measure for in seconds (default 1)\n"
msgstr "-i测量的时间间隔以秒为单位默认 1\n"
#: utils/idle_monitor/cpupower-monitor.c:75
#, c-format
msgid "\t -t: show CPU topology/hierarchy\n"
msgstr "-t显示CPU拓扑/层次结构\n"
#: utils/idle_monitor/cpupower-monitor.c:76
#, c-format
msgid "\t -l: list available CPU sleep monitors (for use with -m)\n"
msgstr "-l列出可用的 CPU 睡眠监视器(与 -m 一起使用)\n"
#: utils/idle_monitor/cpupower-monitor.c:77
#, c-format
msgid "\t -m: show specific CPU sleep monitors only (in same order)\n"
msgstr "-m仅显示特定的CPU睡眠监视器按相同顺序\n"
#: utils/idle_monitor/cpupower-monitor.c:79
#, c-format
msgid ""
"only one of: -t, -l, -m are allowed\n"
"If none of them is passed,"
msgstr ""
"仅允许以下之一:-t、-l、-m\n"
"如果都没有通过的话"
#: utils/idle_monitor/cpupower-monitor.c:80
#, c-format
msgid " all supported monitors are shown\n"
msgstr " 显示所有支持的显示器\n"
#: utils/idle_monitor/cpupower-monitor.c:197
#, c-format
msgid "Monitor %s, Counter %s has no count function. Implementation error\n"
msgstr "监视器 %s、计数器 %s 无计数功能。 执行错误\n"
#: utils/idle_monitor/cpupower-monitor.c:207
#, c-format
msgid " *is offline\n"
msgstr " *离线\n"
#: utils/idle_monitor/cpupower-monitor.c:236
#, c-format
msgid "%s: max monitor name length (%d) exceeded\n"
msgstr "%s超出最大监视器名称长度 (%d)\n"
#: utils/idle_monitor/cpupower-monitor.c:250
#, c-format
msgid "No matching monitor found in %s, try -l option\n"
msgstr "在 %s 中找不到匹配的监视器,请尝试 -l 选项\n"
#: utils/idle_monitor/cpupower-monitor.c:266
#, c-format
msgid "Monitor \"%s\" (%d states) - Might overflow after %u s\n"
msgstr "监视器“%s”%d 状态)- 可能会在 %u 秒后溢出\n"
#: utils/idle_monitor/cpupower-monitor.c:319
#, c-format
msgid "%s took %.5f seconds and exited with status %d\n"
msgstr "%s 用了 %.5f 秒并退出,状态为 %d\n"
#: utils/idle_monitor/cpupower-monitor.c:406
#, c-format
msgid "Cannot read number of available processors\n"
msgstr "无法读取可用处理器的数量\n"
#: utils/idle_monitor/cpupower-monitor.c:417
#, c-format
msgid "Available monitor %s needs root access\n"
msgstr "可用监视器 %s 需要 root 访问权限\n"
#: utils/idle_monitor/cpupower-monitor.c:428
#, c-format
msgid "No HW Cstate monitors found\n"
msgstr "未找到 HW Cstate 监视器\n"
#: utils/cpupower.c:78
#, c-format
msgid "cpupower [ -c cpulist ] subcommand [ARGS]\n"
msgstr "cpupower [ -c cpulist ] subcommand [ARGS]\n"
#: utils/cpupower.c:79
#, c-format
msgid "cpupower --version\n"
msgstr "cpupower --version\n"
#: utils/cpupower.c:80
#, c-format
msgid "Supported subcommands are:\n"
msgstr "支持的子命令有:\n"
#: utils/cpupower.c:83
#, c-format
msgid ""
"\n"
"Some subcommands can make use of the -c cpulist option.\n"
msgstr ""
"\n"
"某些子命令可以使用 -c cpulist 选项。\n"
#: utils/cpupower.c:84
#, c-format
msgid "Look at the general cpupower manpage how to use it\n"
msgstr "看看一般的cpupower manpage如何使用它\n"
#: utils/cpupower.c:85
#, c-format
msgid "and read up the subcommand's manpage whether it is supported.\n"
msgstr "并阅读子命令的manpage是否受支持。\n"
#: utils/cpupower.c:86
#, c-format
msgid ""
"\n"
"Use cpupower help subcommand for getting help for above subcommands.\n"
msgstr ""
"\n"
"使用 cpupower help subcommand获取上述子命令的帮助。\n"
#: utils/cpupower.c:91
#, c-format
msgid "Report errors and bugs to %s, please.\n"
msgstr "请向 %s 报告错误和错误。\n"
#: utils/cpupower.c:114
#, c-format
msgid "Error parsing cpu list\n"
msgstr "解析cpu列表时出错\n"
#: utils/cpupower.c:172
#, c-format
msgid "Subcommand %s needs root privileges\n"
msgstr "子命令 %s 需要 root 权限\n"
#: utils/cpufreq-info.c:31
#, c-format
msgid "Couldn't count the number of CPUs (%s: %s), assuming 1\n"
msgstr "无法计算 CPU 数量(%s%s假设为 1\n"
#: utils/cpufreq-info.c:63
#, c-format
msgid ""
" minimum CPU frequency - maximum CPU frequency - governor\n"
msgstr "最低 CPU 频率 - 最高 CPU 频率 - 调速器\n"
#: utils/cpufreq-info.c:151
#, c-format
msgid "Error while evaluating Boost Capabilities on CPU %d -- are you root?\n"
msgstr "评估 CPU %d 上的 Boost 功能时出错 - 您是 root 吗?\n"
#. P state changes via MSR are identified via cpuid 80000007
#. on Intel and AMD, but we assume boost capable machines can do that
#. if (cpuid_eax(0x80000000) >= 0x80000007
#. && (cpuid_edx(0x80000007) & (1 << 7)))
#.
#: utils/cpufreq-info.c:161
#, c-format
msgid " boost state support: \n"
msgstr " 升压状态支持:\n"
#: utils/cpufreq-info.c:163
#, c-format
msgid " Supported: %s\n"
msgstr " 支持:%s\n"
#: utils/cpufreq-info.c:163 utils/cpufreq-info.c:164
msgid "yes"
msgstr "是"
#: utils/cpufreq-info.c:163 utils/cpufreq-info.c:164
msgid "no"
msgstr "不是"
#: utils/cpufreq-info.c:164
#, c-format
msgid " Active: %s\n"
msgstr " 活跃:%s\n"
#: utils/cpufreq-info.c:177
#, c-format
msgid " Boost States: %d\n"
msgstr " 提升状态:%d\n"
#: utils/cpufreq-info.c:178
#, c-format
msgid " Total States: %d\n"
msgstr " 状态总数:%d\n"
#: utils/cpufreq-info.c:181
#, c-format
msgid " Pstate-Pb%d: %luMHz (boost state)\n"
msgstr " Pstate-Pb%d%luMHz升压状态\n"
#: utils/cpufreq-info.c:184
#, c-format
msgid " Pstate-P%d: %luMHz\n"
msgstr " Pstate-P%d%luMHz\n"
#: utils/cpufreq-info.c:211
#, c-format
msgid " no or unknown cpufreq driver is active on this CPU\n"
msgstr " 该 CPU 上没有或未知的 cpufreq 驱动程序处于活动状态\n"
#: utils/cpufreq-info.c:213
#, c-format
msgid " driver: %s\n"
msgstr " 驱动程序:%s\n"
#: utils/cpufreq-info.c:219
#, c-format
msgid " CPUs which run at the same hardware frequency: "
msgstr " 以相同硬件频率运行的 CPU"
#: utils/cpufreq-info.c:230
#, c-format
msgid " CPUs which need to have their frequency coordinated by software: "
msgstr " 需要通过软件协调频率的 CPU"
#: utils/cpufreq-info.c:241
#, c-format
msgid " maximum transition latency: "
msgstr " 最大转换延迟:"
#: utils/cpufreq-info.c:247
#, c-format
msgid " hardware limits: "
msgstr " 硬件限制:"
#: utils/cpufreq-info.c:256
#, c-format
msgid " available frequency steps: "
msgstr " 可用频率范围:"
#: utils/cpufreq-info.c:269
#, c-format
msgid " available cpufreq governors: "
msgstr " 可用的cpufreq调节器"
#: utils/cpufreq-info.c:280
#, c-format
msgid " current policy: frequency should be within "
msgstr " 当前政策:频率应在"
#: utils/cpufreq-info.c:282
#, c-format
msgid " and "
msgstr "和"
#: utils/cpufreq-info.c:286
#, c-format
msgid ""
"The governor \"%s\" may decide which speed to use\n"
" within this range.\n"
msgstr ""
"调速器“%s”可以决定使用哪种速度\n"
" 在这个范围内。\n"
#: utils/cpufreq-info.c:293
#, c-format
msgid " current CPU frequency is "
msgstr " 当前CPU频率是"
#: utils/cpufreq-info.c:296
#, c-format
msgid " (asserted by call to hardware)"
msgstr " (通过调用硬件来断言)"
#: utils/cpufreq-info.c:304
#, c-format
msgid " cpufreq stats: "
msgstr " cpu频率统计"
#: utils/cpufreq-info.c:472
#, c-format
msgid "Usage: cpupower freqinfo [options]\n"
msgstr "用法cpupower freqinfo [选项]\n"
#: utils/cpufreq-info.c:473 utils/cpufreq-set.c:26 utils/cpupower-set.c:23
#: utils/cpupower-info.c:22 utils/cpuidle-info.c:148
#, c-format
msgid "Options:\n"
msgstr "选项:\n"
#: utils/cpufreq-info.c:474
#, c-format
msgid " -e, --debug Prints out debug information [default]\n"
msgstr " -e, --debug 打印出调试信息[默认]\n"
#: utils/cpufreq-info.c:475
#, c-format
msgid ""
" -f, --freq Get frequency the CPU currently runs at, according\n"
" to the cpufreq core *\n"
msgstr ""
" -f, --freq 获取CPU当前运行的频率根据\n"
" 到 cpufreq 核心 *\n"
#: utils/cpufreq-info.c:477
#, c-format
msgid ""
" -w, --hwfreq Get frequency the CPU currently runs at, by reading\n"
" it from hardware (only available to root) *\n"
msgstr ""
" -w, --hwfreq 通过读取获取CPU当前运行的频率\n"
" 它来自硬件仅适用于root*\n"
#: utils/cpufreq-info.c:479
#, c-format
msgid ""
" -l, --hwlimits Determine the minimum and maximum CPU frequency "
"allowed *\n"
msgstr " -l, --hwlimits 确定允许的最小和最大 CPU 频率 *\n"
#: utils/cpufreq-info.c:480
#, c-format
msgid " -d, --driver Determines the used cpufreq kernel driver *\n"
msgstr " -d, --driver 确定使用的 cpufreq 内核驱动程序 *\n"
#: utils/cpufreq-info.c:481
#, c-format
msgid " -p, --policy Gets the currently used cpufreq policy *\n"
msgstr " -p, --policy 获取当前使用的cpufreq策略 *\n"
#: utils/cpufreq-info.c:482
#, c-format
msgid " -g, --governors Determines available cpufreq governors *\n"
msgstr " -g, --governors 确定可用的 cpufreq 调节器 *\n"
#: utils/cpufreq-info.c:483
#, c-format
msgid ""
" -r, --related-cpus Determines which CPUs run at the same hardware "
"frequency *\n"
msgstr " -r, --lated-cpus 确定哪些 CPU 以相同的硬件频率运行 *\n"
#: utils/cpufreq-info.c:484
#, c-format
msgid ""
" -a, --affected-cpus Determines which CPUs need to have their frequency\n"
" coordinated by software *\n"
msgstr ""
" -a, --affected-cpus 确定哪些 CPU 需要其频率\n"
" 由软件协调*\n"
#: utils/cpufreq-info.c:486
#, c-format
msgid " -s, --stats Shows cpufreq statistics if available\n"
msgstr " -s, --stats 显示 cpufreq 统计信息(如果有)\n"
#: utils/cpufreq-info.c:487
#, c-format
msgid ""
" -y, --latency Determines the maximum latency on CPU frequency "
"changes *\n"
msgstr " -y, --latency 确定 CPU 频率变化的最大延迟*\n"
#: utils/cpufreq-info.c:488
#, c-format
msgid " -b, --boost Checks for turbo or boost modes *\n"
msgstr " -b, --boost 检查 Turbo 或 boost 模式 *\n"
#: utils/cpufreq-info.c:489
#, c-format
msgid ""
" -o, --proc Prints out information like provided by the /proc/"
"cpufreq\n"
" interface in 2.4. and early 2.6. kernels\n"
msgstr ""
" -o, --proc 打印 /proc/cpufreq 提供的信息\n"
" 2.4 中的接口。 以及 2.6 之前的内核。\n"
#: utils/cpufreq-info.c:491
#, c-format
msgid ""
" -m, --human human-readable output for the -f, -w, -s and -y "
"parameters\n"
msgstr " -m, -- human -f, -w, -s 和 -y 参数的人类可读输出\n"
#: utils/cpufreq-info.c:492 utils/cpuidle-info.c:152
#, c-format
msgid " -h, --help Prints out this screen\n"
msgstr " -h, --help 打印此屏幕\n"
#: utils/cpufreq-info.c:495
#, c-format
msgid ""
"If no argument or only the -c, --cpu parameter is given, debug output "
"about\n"
"cpufreq is printed which is useful e.g. for reporting bugs.\n"
msgstr ""
"screen如果没有参数或仅给出了 -c, --cpu 参数,则调试输出有关\n"
"cpufreq 被打印出来,这很有用,例如 用于报告错误。\n"
#: utils/cpufreq-info.c:497
#, c-format
msgid ""
"For the arguments marked with *, omitting the -c or --cpu argument is\n"
"equivalent to setting it to zero\n"
msgstr ""
"对于标有 * 的参数,省略 -c 或 --cpu 参数是\n"
"相当于将其设置为零\n"
#: utils/cpufreq-info.c:580
#, c-format
msgid ""
"The argument passed to this tool can't be combined with passing a --cpu "
"argument\n"
msgstr "传递给此工具的参数不能与传递 --cpu 参数结合使用\n"
#: utils/cpufreq-info.c:596
#, c-format
msgid ""
"You can't specify more than one --cpu parameter and/or\n"
"more than one output-specific argument\n"
msgstr ""
"您不能指定多个 --cpu 参数和/或\n"
"多个特定于输出的参数\n"
#: utils/cpufreq-info.c:600 utils/cpufreq-set.c:82 utils/cpupower-set.c:42
#: utils/cpupower-info.c:42 utils/cpuidle-info.c:213
#, c-format
msgid "invalid or unknown argument\n"
msgstr "无效或未知的参数\n"
#: utils/cpufreq-info.c:617
#, c-format
msgid "couldn't analyze CPU %d as it doesn't seem to be present\n"
msgstr "无法分析 CPU %d因为它似乎不存在\n"
#: utils/cpufreq-info.c:620 utils/cpupower-info.c:142
#, c-format
msgid "analyzing CPU %d:\n"
msgstr "分析 CPU %d\n"
#: utils/cpufreq-set.c:25
#, c-format
msgid "Usage: cpupower frequency-set [options]\n"
msgstr "用法cpupower frequency-set [选项]\n"
#: utils/cpufreq-set.c:27
#, c-format
msgid ""
" -d FREQ, --min FREQ new minimum CPU frequency the governor may "
"select\n"
msgstr " -d FREQ, --min FREQ 调控器可以选择的新的最小 CPU 频率\n"
#: utils/cpufreq-set.c:28
#, c-format
msgid ""
" -u FREQ, --max FREQ new maximum CPU frequency the governor may "
"select\n"
msgstr " -u FREQ, --max FREQ 调控器可以选择的新的最大 CPU 频率\n"
#: utils/cpufreq-set.c:29
#, c-format
msgid " -g GOV, --governor GOV new cpufreq governor\n"
msgstr " -g GOV, --governor GOV 新的 cpufreq 调节器\n"
#: utils/cpufreq-set.c:30
#, c-format
msgid ""
" -f FREQ, --freq FREQ specific frequency to be set. Requires "
"userspace\n"
" governor to be available and loaded\n"
msgstr ""
" -f FREQ, --freq FREQ 要设置的特定频率。 需要用户空间\n"
" 调速器可用并已加载\n"
#: utils/cpufreq-set.c:32
#, c-format
msgid " -r, --related Switches all hardware-related CPUs\n"
msgstr " -r, --related 切换所有与硬件相关的CPU\n"
#: utils/cpufreq-set.c:33 utils/cpupower-set.c:28 utils/cpupower-info.c:27
#, c-format
msgid " -h, --help Prints out this screen\n"
msgstr " -h, --help 打印此屏幕\n"
#: utils/cpufreq-set.c:35
#, c-format
msgid ""
"Notes:\n"
"1. Omitting the -c or --cpu argument is equivalent to setting it to "
"\"all\"\n"
msgstr ""
"注意:\n"
"1.省略-c或--cpu参数相当于将其设置为“all”\n"
#: utils/cpufreq-set.c:37
#, c-format
msgid ""
"2. The -f FREQ, --freq FREQ parameter cannot be combined with any other "
"parameter\n"
" except the -c CPU, --cpu CPU parameter\n"
"3. FREQuencies can be passed in Hz, kHz (default), MHz, GHz, or THz\n"
" by postfixing the value with the wanted unit name, without any space\n"
" (FREQuency in kHz =^ Hz * 0.001 =^ MHz * 1000 =^ GHz * 1000000).\n"
msgstr ""
"2. -f FREQ、--freq FREQ参数不能与任何其他参数组合使用\n"
" 除了 -c CPU、--cpu CPU 参数\n"
"3. 频率可以以 Hz、kHz默认、MHz、GHz 或 THz 为单位传递\n"
" 通过在值后面添加所需的单位名称,不带任何空格\n"
" (以 kHz 为单位的频率 =^ Hz * 0.001 =^ MHz * 1000 =^ GHz * 1000000。\n"
#: utils/cpufreq-set.c:57
#, c-format
msgid ""
"Error setting new values. Common errors:\n"
"- Do you have proper administration rights? (super-user?)\n"
"- Is the governor you requested available and modprobed?\n"
"- Trying to set an invalid policy?\n"
"- Trying to set a specific frequency, but userspace governor is not "
"available,\n"
" for example because of hardware which cannot be set to a specific "
"frequency\n"
" or because the userspace governor isn't loaded?\n"
msgstr ""
"设置新值时出错。 常见错误:\n"
"- 您有适当的管理权吗? (超级用户?)\n"
"- 您请求的调控器是否可用并已进行 modprobed\n"
"- 尝试设置无效的策略?\n"
"- 尝试设置特定频率,但用户空间调控器不可用,\n"
" 例如由于硬件无法设置为特定频率\n"
" 或者因为用户空间调控器未加载?\n"
#: utils/cpufreq-set.c:170
#, c-format
msgid "wrong, unknown or unhandled CPU?\n"
msgstr "错误、未知或未处理的CPU\n"
#: utils/cpufreq-set.c:302
#, c-format
msgid ""
"the -f/--freq parameter cannot be combined with -d/--min, -u/--max or\n"
"-g/--governor parameters\n"
msgstr ""
"-f/--freq 参数不能与 -d/--min、-u/--max 或\n"
"-g/--调速器参数\n"
#: utils/cpufreq-set.c:308
#, c-format
msgid ""
"At least one parameter out of -f/--freq, -d/--min, -u/--max, and\n"
"-g/--governor must be passed\n"
msgstr ""
"-f/--freq、-d/--min、-u/--max 和 -f/--freq 中的至少一个参数\n"
"-g/--governor 必须通过\n"
#: utils/cpufreq-set.c:347
#, c-format
msgid "Setting cpu: %d\n"
msgstr "设置CPU%d\n"
#: utils/cpupower-set.c:22
#, c-format
msgid "Usage: cpupower set [ -b val ] [ -m val ] [ -s val ]\n"
msgstr "用法: cpupower set [ -b val ] [ -m val ] [ -s val ]\n"
#: utils/cpupower-set.c:24
#, c-format
msgid ""
" -b, --perf-bias [VAL] Sets CPU's power vs performance policy on some\n"
" Intel models [0-15], see manpage for details\n"
msgstr ""
" -b, --perf-bias [VAL] 设置 CPU 的功耗与性能策略\n"
" Intel 型号 [0-15]请参阅manpage了解详细信息\n"
#: utils/cpupower-set.c:26
#, c-format
msgid ""
" -m, --sched-mc [VAL] Sets the kernel's multi core scheduler policy.\n"
msgstr " -m, --sched-mc [VAL] 设置内核的多核调度程序策略。\n"
#: utils/cpupower-set.c:27
#, c-format
msgid ""
" -s, --sched-smt [VAL] Sets the kernel's thread sibling scheduler "
"policy.\n"
msgstr " -s, --sched-smt [VAL] 设置内核的线程同级调度程序策略。\n"
#: utils/cpupower-set.c:80
#, c-format
msgid "--perf-bias param out of range [0-%d]\n"
msgstr "--perf-bias 参数超出范围 [0-%d]\n"
#: utils/cpupower-set.c:91
#, c-format
msgid "--sched-mc param out of range [0-%d]\n"
msgstr "--sched-mc 参数超出范围 [0-%d]\n"
#: utils/cpupower-set.c:102
#, c-format
msgid "--sched-smt param out of range [0-%d]\n"
msgstr "--sched-smt 参数超出范围 [0-%d]\n"
#: utils/cpupower-set.c:121
#, c-format
msgid "Error setting sched-mc %s\n"
msgstr "设置 sched-mc %s 时出错\n"
#: utils/cpupower-set.c:127
#, c-format
msgid "Error setting sched-smt %s\n"
msgstr "设置 sched-smt %s 时出错\n"
#: utils/cpupower-set.c:146
#, c-format
msgid "Error setting perf-bias value on CPU %d\n"
msgstr "在 CPU %d 上设置性能偏差值时出错\n"
#: utils/cpupower-info.c:21
#, c-format
msgid "Usage: cpupower info [ -b ] [ -m ] [ -s ]\n"
msgstr "用法cpupower info [-b][-m][-s]\n"
#: utils/cpupower-info.c:23
#, c-format
msgid ""
" -b, --perf-bias Gets CPU's power vs performance policy on some\n"
" Intel models [0-15], see manpage for details\n"
msgstr ""
" -b, --perf-bias 获取 CPU 在某些方面的功耗与性能策略\n"
" Intel 型号 [0-15],请参阅联机帮助页了解详细信"
"息\n"
#: utils/cpupower-info.c:25
#, c-format
msgid " -m, --sched-mc Gets the kernel's multi core scheduler policy.\n"
msgstr " -m, --sched-mc 获取内核的多核调度程序策略。\n"
#: utils/cpupower-info.c:26
#, c-format
msgid ""
" -s, --sched-smt Gets the kernel's thread sibling scheduler policy.\n"
msgstr " -s, --sched-smt 获取内核的线程同级调度程序策略。\n"
#: utils/cpupower-info.c:28
#, c-format
msgid ""
"\n"
"Passing no option will show all info, by default only on core 0\n"
msgstr ""
"\n"
"不传递任何选项将显示所有信息,默认情况下仅在核心 0 上\n"
#: utils/cpupower-info.c:102
#, c-format
msgid "System's multi core scheduler setting: "
msgstr "系统的多核调度器设置:"
#. if sysfs file is missing it's: errno == ENOENT
#: utils/cpupower-info.c:105 utils/cpupower-info.c:114
#, c-format
msgid "not supported\n"
msgstr "不支持\n"
#: utils/cpupower-info.c:111
#, c-format
msgid "System's thread sibling scheduler setting: "
msgstr "系统的线程兄调度程序设置:"
#: utils/cpupower-info.c:126
#, c-format
msgid "Intel's performance bias setting needs root privileges\n"
msgstr "Intel的性能偏差设置需要root权限\n"
#: utils/cpupower-info.c:128
#, c-format
msgid "System does not support Intel's performance bias setting\n"
msgstr "系统不支持Intel的性能偏差设置\n"
#: utils/cpupower-info.c:147
#, c-format
msgid "Could not read perf-bias value\n"
msgstr "无法读取性能偏差值\n"
#: utils/cpupower-info.c:150
#, c-format
msgid "perf-bias: %d\n"
msgstr "性能偏差:%d\n"
#: utils/cpuidle-info.c:28
#, c-format
msgid "Analyzing CPU %d:\n"
msgstr "正在分析 CPU %d\n"
#: utils/cpuidle-info.c:32
#, c-format
msgid "CPU %u: No idle states\n"
msgstr "CPU %u无空闲状态\n"
#: utils/cpuidle-info.c:36
#, c-format
msgid "CPU %u: Can't read idle state info\n"
msgstr "CPU %u无法读取空闲状态信息\n"
#: utils/cpuidle-info.c:41
#, c-format
msgid "Could not determine max idle state %u\n"
msgstr "无法确定最大空闲状态 %u\n"
#: utils/cpuidle-info.c:46
#, c-format
msgid "Number of idle states: %d\n"
msgstr "空闲状态数:%d\n"
#: utils/cpuidle-info.c:48
#, c-format
msgid "Available idle states:"
msgstr "可用的空闲状态:"
#: utils/cpuidle-info.c:71
#, c-format
msgid "Flags/Description: %s\n"
msgstr "标志/描述:%s\n"
#: utils/cpuidle-info.c:74
#, c-format
msgid "Latency: %lu\n"
msgstr "延迟:%lu\n"
#: utils/cpuidle-info.c:76
#, c-format
msgid "Usage: %lu\n"
msgstr "用法:%lu\n"
#: utils/cpuidle-info.c:78
#, c-format
msgid "Duration: %llu\n"
msgstr "持续时间:%llu\n"
#: utils/cpuidle-info.c:90
#, c-format
msgid "Could not determine cpuidle driver\n"
msgstr "无法确定 cpuidle 驱动程序\n"
#: utils/cpuidle-info.c:94
#, c-format
msgid "CPUidle driver: %s\n"
msgstr "CPU 空闲驱动程序:%s\n"
#: utils/cpuidle-info.c:99
#, c-format
msgid "Could not determine cpuidle governor\n"
msgstr "无法确定 cpuidle 调控器\n"
#: utils/cpuidle-info.c:103
#, c-format
msgid "CPUidle governor: %s\n"
msgstr "CPU 空闲调节器:%s\n"
#: utils/cpuidle-info.c:122
#, c-format
msgid "CPU %u: Can't read C-state info\n"
msgstr "CPU %u无法读取 C 状态信息\n"
#. printf("Cstates: %d\n", cstates);
#: utils/cpuidle-info.c:127
#, c-format
msgid "active state: C0\n"
msgstr "活动状态: C0\n"
#: utils/cpuidle-info.c:128
#, c-format
msgid "max_cstate: C%u\n"
msgstr "最大c状态: C%u\n"
#: utils/cpuidle-info.c:129
#, c-format
msgid "maximum allowed latency: %lu usec\n"
msgstr "允许的最大延迟:%lu usec\n"
#: utils/cpuidle-info.c:130
#, c-format
msgid "states:\t\n"
msgstr "状态:\t\n"
#: utils/cpuidle-info.c:132
#, c-format
msgid " C%d: type[C%d] "
msgstr " C%d: 类型[C%d]"
#: utils/cpuidle-info.c:134
#, c-format
msgid "promotion[--] demotion[--] "
msgstr "晋升[--] 降级[--]"
#: utils/cpuidle-info.c:135
#, c-format
msgid "latency[%03lu] "
msgstr "延迟[%03lu]"
#: utils/cpuidle-info.c:137
#, c-format
msgid "usage[%08lu] "
msgstr "使用情况[%08lu]"
#: utils/cpuidle-info.c:139
#, c-format
msgid "duration[%020Lu] \n"
msgstr "持续时间[%020Lu]\n"
#: utils/cpuidle-info.c:147
#, c-format
msgid "Usage: cpupower idleinfo [options]\n"
msgstr "用法cpupower idleinfo [选项]\n"
#: utils/cpuidle-info.c:149
#, c-format
msgid " -s, --silent Only show general C-state information\n"
msgstr " -s, --silent 只显示一般C状态信息\n"
#: utils/cpuidle-info.c:150
#, c-format
msgid ""
" -o, --proc Prints out information like provided by the /proc/"
"acpi/processor/*/power\n"
" interface in older kernels\n"
msgstr ""
" -o, --proc 打印 /proc/acpi/processor/*/power 提供的信息\n"
" 旧内核中的接口\n"
#: utils/cpuidle-info.c:209
#, c-format
msgid "You can't specify more than one output-specific argument\n"
msgstr "您不能指定多个特定于输出的参数\n"
#~ msgid ""
#~ " -c CPU, --cpu CPU CPU number which information shall be determined "
#~ "about\n"
#~ msgstr ""
#~ " -c CPU, --cpu CPU Numéro du CPU pour lequel l'information sera "
#~ "affichée\n"
#~ msgid ""
#~ " -c CPU, --cpu CPU number of CPU where cpufreq settings shall be "
#~ "modified\n"
#~ msgstr ""
#~ " -c CPU, --cpu CPU numéro du CPU à prendre en compte pour les\n"
#~ " changements\n"

View File

@ -81,6 +81,9 @@ as resume failures.
.TP .TP
\fB-wifitrace\fR \fB-wifitrace\fR
Trace through the wifi reconnect time and include it in the timeline. Trace through the wifi reconnect time and include it in the timeline.
.TP
\fB-debugtiming\fR
Add timestamp to each printed output line, accurate to the millisecond.
.SS "advanced" .SS "advanced"
.TP .TP

View File

@ -18,7 +18,7 @@
# #
# Links: # Links:
# Home Page # Home Page
# https://01.org/pm-graph # https://www.intel.com/content/www/us/en/developer/topic-technology/open/pm-graph/overview.html
# Source repo # Source repo
# git@github.com:intel/pm-graph # git@github.com:intel/pm-graph
# #
@ -65,6 +65,7 @@ import gzip
from threading import Thread from threading import Thread
from subprocess import call, Popen, PIPE from subprocess import call, Popen, PIPE
import base64 import base64
import traceback
debugtiming = False debugtiming = False
mystarttime = time.time() mystarttime = time.time()
@ -86,7 +87,7 @@ def ascii(text):
# store system values and test parameters # store system values and test parameters
class SystemValues: class SystemValues:
title = 'SleepGraph' title = 'SleepGraph'
version = '5.12' version = '5.13'
ansi = False ansi = False
rs = 0 rs = 0
display = '' display = ''
@ -236,7 +237,11 @@ class SystemValues:
'msleep': { 'args_x86_64': {'time':'%di:s32'}, 'ub': 1 }, 'msleep': { 'args_x86_64': {'time':'%di:s32'}, 'ub': 1 },
'schedule_timeout': { 'args_x86_64': {'timeout':'%di:s32'}, 'ub': 1 }, 'schedule_timeout': { 'args_x86_64': {'timeout':'%di:s32'}, 'ub': 1 },
'udelay': { 'func':'__const_udelay', 'args_x86_64': {'loops':'%di:s32'}, 'ub': 1 }, 'udelay': { 'func':'__const_udelay', 'args_x86_64': {'loops':'%di:s32'}, 'ub': 1 },
'usleep_range': { 'args_x86_64': {'min':'%di:s32', 'max':'%si:s32'}, 'ub': 1 }, 'usleep_range': {
'func':'usleep_range_state',
'args_x86_64': {'min':'%di:s32', 'max':'%si:s32'},
'ub': 1
},
'mutex_lock_slowpath': { 'func':'__mutex_lock_slowpath', 'ub': 1 }, 'mutex_lock_slowpath': { 'func':'__mutex_lock_slowpath', 'ub': 1 },
'acpi_os_stall': {'ub': 1}, 'acpi_os_stall': {'ub': 1},
'rt_mutex_slowlock': {'ub': 1}, 'rt_mutex_slowlock': {'ub': 1},
@ -342,15 +347,21 @@ class SystemValues:
if self.verbose or msg.startswith('WARNING:'): if self.verbose or msg.startswith('WARNING:'):
pprint(msg) pprint(msg)
def signalHandler(self, signum, frame): def signalHandler(self, signum, frame):
if not self.result:
return
signame = self.signames[signum] if signum in self.signames else 'UNKNOWN' signame = self.signames[signum] if signum in self.signames else 'UNKNOWN'
msg = 'Signal %s caused a tool exit, line %d' % (signame, frame.f_lineno) if signame in ['SIGUSR1', 'SIGUSR2', 'SIGSEGV']:
traceback.print_stack()
stack = traceback.format_list(traceback.extract_stack())
self.outputResult({'stack':stack})
if signame == 'SIGUSR1':
return
msg = '%s caused a tool exit, line %d' % (signame, frame.f_lineno)
pprint(msg)
self.outputResult({'error':msg}) self.outputResult({'error':msg})
os.kill(os.getpid(), signal.SIGKILL)
sys.exit(3) sys.exit(3)
def signalHandlerInit(self): def signalHandlerInit(self):
capture = ['BUS', 'SYS', 'XCPU', 'XFSZ', 'PWR', 'HUP', 'INT', 'QUIT', capture = ['BUS', 'SYS', 'XCPU', 'XFSZ', 'PWR', 'HUP', 'INT', 'QUIT',
'ILL', 'ABRT', 'FPE', 'SEGV', 'TERM'] 'ILL', 'ABRT', 'FPE', 'SEGV', 'TERM', 'USR1', 'USR2']
self.signames = dict() self.signames = dict()
for i in capture: for i in capture:
s = 'SIG'+i s = 'SIG'+i
@ -859,6 +870,11 @@ class SystemValues:
# files needed for any trace data # files needed for any trace data
files = ['buffer_size_kb', 'current_tracer', 'trace', 'trace_clock', files = ['buffer_size_kb', 'current_tracer', 'trace', 'trace_clock',
'trace_marker', 'trace_options', 'tracing_on'] 'trace_marker', 'trace_options', 'tracing_on']
# legacy check for old systems
if not os.path.exists(self.tpath+'trace'):
self.tpath = '/sys/kernel/debug/tracing/'
if not os.path.exists(self.epath):
self.epath = '/sys/kernel/debug/tracing/events/power/'
# files needed for callgraph trace data # files needed for callgraph trace data
tp = self.tpath tp = self.tpath
if(self.usecallgraph): if(self.usecallgraph):
@ -911,6 +927,13 @@ class SystemValues:
if num > 0: if num > 0:
n = '%d' % num n = '%d' % num
fp = open(self.result, 'a') fp = open(self.result, 'a')
if 'stack' in testdata:
fp.write('Printing stack trace:\n')
for line in testdata['stack']:
fp.write(line)
fp.close()
self.sudoUserchown(self.result)
return
if 'error' in testdata: if 'error' in testdata:
fp.write('result%s: fail\n' % n) fp.write('result%s: fail\n' % n)
fp.write('error%s: %s\n' % (n, testdata['error'])) fp.write('error%s: %s\n' % (n, testdata['error']))
@ -1980,7 +2003,7 @@ class Data:
length = -1.0 length = -1.0
if(start >= 0 and end >= 0): if(start >= 0 and end >= 0):
length = end - start length = end - start
if pid == -2 or name not in sysvals.tracefuncs.keys(): if pid >= -2:
i = 2 i = 2
origname = name origname = name
while(name in list): while(name in list):
@ -2753,7 +2776,8 @@ class Timeline:
def createHeader(self, sv, stamp): def createHeader(self, sv, stamp):
if(not stamp['time']): if(not stamp['time']):
return return
self.html += '<div class="version"><a href="https://01.org/pm-graph">%s v%s</a></div>' \ self.html += '<div class="version"><a href="https://www.intel.com/content/www/'+\
'us/en/developer/topic-technology/open/pm-graph/overview.html">%s v%s</a></div>' \
% (sv.title, sv.version) % (sv.title, sv.version)
if sv.logmsg and sv.testlog: if sv.logmsg and sv.testlog:
self.html += '<button id="showtest" class="logbtn btnfmt">log</button>' self.html += '<button id="showtest" class="logbtn btnfmt">log</button>'
@ -5238,12 +5262,16 @@ def addScriptCode(hf, testruns):
} }
var info = dev[i].title.split(" "); var info = dev[i].title.split(" ");
var pname = info[info.length-1]; var pname = info[info.length-1];
pd[pname] = parseFloat(info[info.length-3].slice(1)); var length = parseFloat(info[info.length-3].slice(1));
total[0] += pd[pname]; if (pname in pd)
if(pname.indexOf("suspend") >= 0) pd[pname] += length;
total[tidx] += pd[pname];
else else
total[tidx+1] += pd[pname]; pd[pname] = length;
total[0] += length;
if(pname.indexOf("suspend") >= 0)
total[tidx] += length;
else
total[tidx+1] += length;
} }
} }
var devname = deviceTitle(this.title, total, cpu); var devname = deviceTitle(this.title, total, cpu);
@ -5262,7 +5290,7 @@ def addScriptCode(hf, testruns):
phases[i].style.left = left+"%"; phases[i].style.left = left+"%";
phases[i].title = phases[i].id+" "+pd[phases[i].id]+" ms"; phases[i].title = phases[i].id+" "+pd[phases[i].id]+" ms";
left += w; left += w;
var time = "<t4 style=\"font-size:"+fs+"px\">"+pd[phases[i].id]+" ms<br></t4>"; var time = "<t4 style=\"font-size:"+fs+"px\">"+pd[phases[i].id].toFixed(3)+" ms<br></t4>";
var pname = "<t3 style=\"font-size:"+fs2+"px\">"+phases[i].id.replace(new RegExp("_", "g"), " ")+"</t3>"; var pname = "<t3 style=\"font-size:"+fs2+"px\">"+phases[i].id.replace(new RegExp("_", "g"), " ")+"</t3>";
phases[i].innerHTML = time+pname; phases[i].innerHTML = time+pname;
} else { } else {
@ -6742,6 +6770,7 @@ def printHelp():
' -wifi If a wifi connection is available, check that it reconnects after resume.\n'\ ' -wifi If a wifi connection is available, check that it reconnects after resume.\n'\
' -wifitrace Trace kernel execution through wifi reconnect.\n'\ ' -wifitrace Trace kernel execution through wifi reconnect.\n'\
' -netfix Use netfix to reset the network in the event it fails to resume.\n'\ ' -netfix Use netfix to reset the network in the event it fails to resume.\n'\
' -debugtiming Add timestamp to each printed line\n'\
' [testprep]\n'\ ' [testprep]\n'\
' -sync Sync the filesystems before starting the test\n'\ ' -sync Sync the filesystems before starting the test\n'\
' -rs on/off Enable/disable runtime suspend for all devices, restore all after test\n'\ ' -rs on/off Enable/disable runtime suspend for all devices, restore all after test\n'\
@ -7047,7 +7076,6 @@ if __name__ == '__main__':
except: except:
doError('No result file supplied', True) doError('No result file supplied', True)
sysvals.result = val sysvals.result = val
sysvals.signalHandlerInit()
else: else:
doError('Invalid argument: '+arg, True) doError('Invalid argument: '+arg, True)
@ -7057,6 +7085,7 @@ if __name__ == '__main__':
if(sysvals.usecallgraph and sysvals.useprocmon): if(sysvals.usecallgraph and sysvals.useprocmon):
doError('-proc is not compatible with -f') doError('-proc is not compatible with -f')
sysvals.signalHandlerInit()
if sysvals.usecallgraph and sysvals.cgskip: if sysvals.usecallgraph and sysvals.cgskip:
sysvals.vprint('Using cgskip file: %s' % sysvals.cgskip) sysvals.vprint('Using cgskip file: %s' % sysvals.cgskip)
sysvals.setCallgraphBlacklist(sysvals.cgskip) sysvals.setCallgraphBlacklist(sysvals.cgskip)