hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I99VMF CVE: NA
--------------------------------
When turning on turbo, if frequency configuration takes effect slowly, the updated policy->cur may be equal to the frequency configured in governor->limits(), performance governor will not adjust the frequency, configured frequency will remain at turbo-freq.
Simplified call stack looks as follows: cpufreq_register_driver(&cppc_cpufreq_driver) ... cppc_cpufreq_cpu_init() cppc_get_perf_caps() policy->max = cppc_perf_to_khz(caps, caps->nominal_perf) cppc_set_perf(highest_perf) // set highest_perf policy->cur = cpufreq_driver->get() // if cur == policy->max cpufreq_init_policy() ... cpufreq_start_governor() // governor: performance new_freq = cpufreq_driver->get() // if new_freq == policy->max if (policy->cur != new_freq) cpufreq_out_of_sync(policy, new_freq) ... policy->cur = new_freq ... policy->governor->limits() __cpufreq_driver_target(policy->max) if (policy->cur==target) // generate error, keep set highest_perf ret cppc_set_perf(target)
Fix this by changing highest_perf to nominal_perf in cppc_cpufreq_cpu_init().
Fixes: 5477fb3bd1e8 ("ACPI / CPPC: Add a CPUFreq driver for use with CPPC") Signed-off-by: liwei liwei728@huawei.com --- drivers/cpufreq/cppc_cpufreq.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c index 156ef2c40464..dc91bc6f7b8d 100644 --- a/drivers/cpufreq/cppc_cpufreq.c +++ b/drivers/cpufreq/cppc_cpufreq.c @@ -307,15 +307,15 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy) if (cpu_data->perf_caps.highest_perf > cpu_data->perf_caps.nominal_perf) boost_supported = true;
- /* Set policy->cur to max now. The governors will adjust later. */ + /* Set policy->cur to norm now. */ policy->cur = cppc_cpufreq_perf_to_khz(cpu_data, - cpu_data->perf_caps.highest_perf); - cpu_data->perf_ctrls.desired_perf = cpu_data->perf_caps.highest_perf; + cpu_data->perf_caps.nominal_perf); + cpu_data->perf_ctrls.desired_perf = cpu_data->perf_caps.nominal_perf;
ret = cppc_set_perf(cpu, &cpu_data->perf_ctrls); if (ret) pr_debug("Err setting perf value:%d on CPU:%d. ret:%d\n", - cpu_data->perf_caps.highest_perf, cpu, ret); + cpu_data->perf_caps.nominal_perf, cpu, ret);
return ret; }