aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-10-24 17:20:25 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-10-24 17:20:25 -0400
commit2f1d407adab026b34a105ed27b1d4d7e910c4448 (patch)
tree1c5f14db4f9417a9d709d065a7bc2bf057a8053e
parenta6c6ead14183ea4ec8ce7551e1f3451024b9c4db (diff)
cpufreq: intel_pstate: Always set max P-state in performance mode
The only times at which intel_pstate checks the policy set for a given CPU is the initialization of that CPU and updates of its policy settings from cpufreq when intel_pstate_set_policy() is invoked. That is insufficient, however, because intel_pstate uses the same P-state selection function for all CPUs regardless of the policy setting for each of them and the P-state limits are shared between them. Thus if the policy is set to "performance" for a particular CPU, it may not behave as expected if the cpufreq settings are changed subsequently for another CPU. That can be easily demonstrated by writing "performance" to scaling_governor for all CPUs and then switching it to "powersave" for one of them in which case all of the CPUs will behave as though their scaling_governor were all "powersave" (even though the policy still appears to be "performance" for the remaining CPUs). Fix this problem by modifying intel_pstate_adjust_busy_pstate() to always set the P-state to the maximum allowed by the current limits for all CPUs whose policy is set to "performance". Note that it still is recommended to always change the policy setting in the same way for all CPUs even with this fix applied to avoid confusion. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/cpufreq/intel_pstate.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index ac7c58d20b58..4737520ec823 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -179,6 +179,7 @@ struct _pid {
179/** 179/**
180 * struct cpudata - Per CPU instance data storage 180 * struct cpudata - Per CPU instance data storage
181 * @cpu: CPU number for this instance data 181 * @cpu: CPU number for this instance data
182 * @policy: CPUFreq policy value
182 * @update_util: CPUFreq utility callback information 183 * @update_util: CPUFreq utility callback information
183 * @update_util_set: CPUFreq utility callback is set 184 * @update_util_set: CPUFreq utility callback is set
184 * @iowait_boost: iowait-related boost fraction 185 * @iowait_boost: iowait-related boost fraction
@@ -201,6 +202,7 @@ struct _pid {
201struct cpudata { 202struct cpudata {
202 int cpu; 203 int cpu;
203 204
205 unsigned int policy;
204 struct update_util_data update_util; 206 struct update_util_data update_util;
205 bool update_util_set; 207 bool update_util_set;
206 208
@@ -1337,7 +1339,8 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
1337 1339
1338 from = cpu->pstate.current_pstate; 1340 from = cpu->pstate.current_pstate;
1339 1341
1340 target_pstate = pstate_funcs.get_target_pstate(cpu); 1342 target_pstate = cpu->policy == CPUFREQ_POLICY_PERFORMANCE ?
1343 cpu->pstate.turbo_pstate : pstate_funcs.get_target_pstate(cpu);
1341 1344
1342 intel_pstate_update_pstate(cpu, target_pstate); 1345 intel_pstate_update_pstate(cpu, target_pstate);
1343 1346
@@ -1504,6 +1507,8 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
1504 policy->cpuinfo.max_freq, policy->max); 1507 policy->cpuinfo.max_freq, policy->max);
1505 1508
1506 cpu = all_cpu_data[policy->cpu]; 1509 cpu = all_cpu_data[policy->cpu];
1510 cpu->policy = policy->policy;
1511
1507 if (cpu->pstate.max_pstate_physical > cpu->pstate.max_pstate && 1512 if (cpu->pstate.max_pstate_physical > cpu->pstate.max_pstate &&
1508 policy->max < policy->cpuinfo.max_freq && 1513 policy->max < policy->cpuinfo.max_freq &&
1509 policy->max > cpu->pstate.max_pstate * cpu->pstate.scaling) { 1514 policy->max > cpu->pstate.max_pstate * cpu->pstate.scaling) {
@@ -1511,7 +1516,7 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
1511 policy->max = policy->cpuinfo.max_freq; 1516 policy->max = policy->cpuinfo.max_freq;
1512 } 1517 }
1513 1518
1514 if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) { 1519 if (cpu->policy == CPUFREQ_POLICY_PERFORMANCE) {
1515 limits = &performance_limits; 1520 limits = &performance_limits;
1516 if (policy->max >= policy->cpuinfo.max_freq) { 1521 if (policy->max >= policy->cpuinfo.max_freq) {
1517 pr_debug("set performance\n"); 1522 pr_debug("set performance\n");
@@ -1547,7 +1552,7 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
1547 limits->max_perf = round_up(limits->max_perf, FRAC_BITS); 1552 limits->max_perf = round_up(limits->max_perf, FRAC_BITS);
1548 1553
1549 out: 1554 out:
1550 if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) { 1555 if (cpu->policy == CPUFREQ_POLICY_PERFORMANCE) {
1551 /* 1556 /*
1552 * NOHZ_FULL CPUs need this as the governor callback may not 1557 * NOHZ_FULL CPUs need this as the governor callback may not
1553 * be invoked on them. 1558 * be invoked on them.