Skip to content

Commit 2f1d407

Browse files
committed
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>
1 parent a6c6ead commit 2f1d407

1 file changed

Lines changed: 8 additions & 3 deletions

File tree

drivers/cpufreq/intel_pstate.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ struct _pid {
179179
/**
180180
* struct cpudata - Per CPU instance data storage
181181
* @cpu: CPU number for this instance data
182+
* @policy: CPUFreq policy value
182183
* @update_util: CPUFreq utility callback information
183184
* @update_util_set: CPUFreq utility callback is set
184185
* @iowait_boost: iowait-related boost fraction
@@ -201,6 +202,7 @@ struct _pid {
201202
struct cpudata {
202203
int cpu;
203204

205+
unsigned int policy;
204206
struct update_util_data update_util;
205207
bool update_util_set;
206208

@@ -1337,7 +1339,8 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
13371339

13381340
from = cpu->pstate.current_pstate;
13391341

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);
13411344

13421345
intel_pstate_update_pstate(cpu, target_pstate);
13431346

@@ -1504,14 +1507,16 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
15041507
policy->cpuinfo.max_freq, policy->max);
15051508

15061509
cpu = all_cpu_data[policy->cpu];
1510+
cpu->policy = policy->policy;
1511+
15071512
if (cpu->pstate.max_pstate_physical > cpu->pstate.max_pstate &&
15081513
policy->max < policy->cpuinfo.max_freq &&
15091514
policy->max > cpu->pstate.max_pstate * cpu->pstate.scaling) {
15101515
pr_debug("policy->max > max non turbo frequency\n");
15111516
policy->max = policy->cpuinfo.max_freq;
15121517
}
15131518

1514-
if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
1519+
if (cpu->policy == CPUFREQ_POLICY_PERFORMANCE) {
15151520
limits = &performance_limits;
15161521
if (policy->max >= policy->cpuinfo.max_freq) {
15171522
pr_debug("set performance\n");
@@ -1547,7 +1552,7 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
15471552
limits->max_perf = round_up(limits->max_perf, FRAC_BITS);
15481553

15491554
out:
1550-
if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
1555+
if (cpu->policy == CPUFREQ_POLICY_PERFORMANCE) {
15511556
/*
15521557
* NOHZ_FULL CPUs need this as the governor callback may not
15531558
* be invoked on them.

0 commit comments

Comments
 (0)