Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

cpufreq: intel_pstate: Update cpuinfo.max_freq on HWP_CAP changes

With HWP enabled, when the turbo range of performance levels is
disabled by the platform firmware, the CPU capacity is given by
the "guaranteed performance" field in MSR_HWP_CAPABILITIES which
is generally dynamic. When it changes, the kernel receives an HWP
notification interrupt handled by notify_hwp_interrupt().

When the "guaranteed performance" value changes in the above
configuration, the CPU performance scaling needs to be adjusted so
as to use the new CPU capacity in computations, which means that
the cpuinfo.max_freq value needs to be updated for that CPU.

Accordingly, modify intel_pstate_notify_work() to read
MSR_HWP_CAPABILITIES and update cpuinfo.max_freq to reflect the
new configuration (this update can be carried out even if the
configuration doesn't actually change, because it simply doesn't
matter then and it takes less time to update it than to do extra
checks to decide whether or not a change has really occurred).

Reported-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Tested-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

+17 -7
+17 -7
drivers/cpufreq/intel_pstate.c
··· 1134 1134 cpufreq_update_policy(cpu); 1135 1135 } 1136 1136 1137 + static void __intel_pstate_update_max_freq(struct cpudata *cpudata, 1138 + struct cpufreq_policy *policy) 1139 + { 1140 + policy->cpuinfo.max_freq = global.turbo_disabled_mf ? 1141 + cpudata->pstate.max_freq : cpudata->pstate.turbo_freq; 1142 + refresh_frequency_limits(policy); 1143 + } 1144 + 1137 1145 static void intel_pstate_update_max_freq(unsigned int cpu) 1138 1146 { 1139 1147 struct cpufreq_policy *policy = cpufreq_cpu_acquire(cpu); 1140 - struct cpudata *cpudata; 1141 1148 1142 1149 if (!policy) 1143 1150 return; 1144 1151 1145 - cpudata = all_cpu_data[cpu]; 1146 - policy->cpuinfo.max_freq = global.turbo_disabled_mf ? 1147 - cpudata->pstate.max_freq : cpudata->pstate.turbo_freq; 1148 - 1149 - refresh_frequency_limits(policy); 1152 + __intel_pstate_update_max_freq(all_cpu_data[cpu], policy); 1150 1153 1151 1154 cpufreq_cpu_release(policy); 1152 1155 } ··· 1597 1594 { 1598 1595 struct cpudata *cpudata = 1599 1596 container_of(to_delayed_work(work), struct cpudata, hwp_notify_work); 1597 + struct cpufreq_policy *policy = cpufreq_cpu_acquire(cpudata->cpu); 1600 1598 1601 - cpufreq_update_policy(cpudata->cpu); 1599 + if (policy) { 1600 + intel_pstate_get_hwp_cap(cpudata); 1601 + __intel_pstate_update_max_freq(cpudata, policy); 1602 + 1603 + cpufreq_cpu_release(policy); 1604 + } 1605 + 1602 1606 wrmsrl_on_cpu(cpudata->cpu, MSR_HWP_STATUS, 0); 1603 1607 } 1604 1608