Skip to content

Commit de002c5

Browse files
committed
cpufreq: intel_pstate: Fix EPP setting via sysfs in active mode
Because intel_pstate_set_energy_pref_index() reads and writes the MSR_HWP_REQUEST register without using the cached value of it used by intel_pstate_hwp_boost_up() and intel_pstate_hwp_boost_down(), those functions may overwrite the value written by it and so the EPP value set via sysfs may be lost. To avoid that, make intel_pstate_set_energy_pref_index() take the cached value of MSR_HWP_REQUEST just like the other two routines mentioned above and update it with the new EPP value coming from user space in addition to updating the MSR. Note that the MSR itself still needs to be updated too in case hwp_boost is unset or the boosting mechanism is not active at the EPP change time. Fixes: e0efd5b ("cpufreq: intel_pstate: Add HWP boost utility and sched util hooks") Reported-by: Francisco Jerez <[email protected]> Cc: 4.18+ <[email protected]> # 4.18+: 3da97d4 cpufreq: intel_pstate: Rearrange ... Signed-off-by: Rafael J. Wysocki <[email protected]> Reviewed-by: Francisco Jerez <[email protected]>
1 parent 3a95717 commit de002c5

File tree

1 file changed

+12
-5
lines changed

1 file changed

+12
-5
lines changed

drivers/cpufreq/intel_pstate.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -650,11 +650,12 @@ static int intel_pstate_set_energy_pref_index(struct cpudata *cpu_data,
650650
epp = cpu_data->epp_default;
651651

652652
if (boot_cpu_has(X86_FEATURE_HWP_EPP)) {
653-
u64 value;
654-
655-
ret = rdmsrl_on_cpu(cpu_data->cpu, MSR_HWP_REQUEST, &value);
656-
if (ret)
657-
return ret;
653+
/*
654+
* Use the cached HWP Request MSR value, because the register
655+
* itself may be updated by intel_pstate_hwp_boost_up() or
656+
* intel_pstate_hwp_boost_down() at any time.
657+
*/
658+
u64 value = READ_ONCE(cpu_data->hwp_req_cached);
658659

659660
value &= ~GENMASK_ULL(31, 24);
660661

@@ -664,6 +665,12 @@ static int intel_pstate_set_energy_pref_index(struct cpudata *cpu_data,
664665
epp = epp_values[pref_index - 1];
665666

666667
value |= (u64)epp << 24;
668+
/*
669+
* The only other updater of hwp_req_cached in the active mode,
670+
* intel_pstate_hwp_set(), is called under the same lock as this
671+
* function, so it cannot run in parallel with the update below.
672+
*/
673+
WRITE_ONCE(cpu_data->hwp_req_cached, value);
667674
ret = wrmsrl_on_cpu(cpu_data->cpu, MSR_HWP_REQUEST, value);
668675
} else {
669676
if (epp == -EINVAL)

0 commit comments

Comments
 (0)