ANDROID: Revert "cpufreq: Avoid using inconsistent policy->min and policy->max"
The combination of the cpufreq changes that came in with v6.12.28, commit573b047229("cpufreq: Avoid using inconsistent policy->min and policy->max") and commit962d88304c("cpufreq: Fix setting policy limits when frequency tables are used") unfortunately broke the KABI. The second of which was reverted inad2b007ef4("Revert "cpufreq: Fix setting policy limits when frequency tables are used""). However, that change is actually a necessary fix to the first. As the refactoring to passing the max and min through the arguments couldn't be done without KABI impact, the changes to be more consistent with policy->min/max ends up introducing a subtle problem where the new max value being set ends up being clamped to the current max value - thus cpufreq max can be reduced but not increased (with the min increased but not decreased). A minimal fix of this effectively undoes the key point of commit573b047229, so it seems best to revert the whole thing for now. I think the small pre-existing risk of the policy->max/min values being read when shortly to an intermediate value before getting assigned the final value seems to be less problematic in practice. Fixes:ad2b007ef4("Revert "cpufreq: Fix setting policy limits when frequency tables are used"") Bug: 428984800 Signed-off-by: John Stultz <jstultz@google.com> Change-Id: I5a76cc2b0056071ffa26a682458df5fe0a4b83a3
This commit is contained in:
committed by
Treehugger Robot
parent
15d2fe0544
commit
a7e1300b95
@@ -543,6 +543,7 @@ static unsigned int __resolve_freq(struct cpufreq_policy *policy,
|
||||
unsigned int idx;
|
||||
unsigned int old_target_freq = target_freq;
|
||||
|
||||
target_freq = clamp_val(target_freq, policy->min, policy->max);
|
||||
trace_android_vh_cpufreq_resolve_freq(policy, &target_freq, old_target_freq);
|
||||
|
||||
if (!policy->freq_table)
|
||||
@@ -568,22 +569,7 @@ static unsigned int __resolve_freq(struct cpufreq_policy *policy,
|
||||
unsigned int cpufreq_driver_resolve_freq(struct cpufreq_policy *policy,
|
||||
unsigned int target_freq)
|
||||
{
|
||||
unsigned int min = READ_ONCE(policy->min);
|
||||
unsigned int max = READ_ONCE(policy->max);
|
||||
|
||||
/*
|
||||
* If this function runs in parallel with cpufreq_set_policy(), it may
|
||||
* read policy->min before the update and policy->max after the update
|
||||
* or the other way around, so there is no ordering guarantee.
|
||||
*
|
||||
* Resolve this by always honoring the max (in case it comes from
|
||||
* thermal throttling or similar).
|
||||
*/
|
||||
if (unlikely(min > max))
|
||||
min = max;
|
||||
|
||||
return __resolve_freq(policy, clamp_val(target_freq, min, max),
|
||||
CPUFREQ_RELATION_LE);
|
||||
return __resolve_freq(policy, target_freq, CPUFREQ_RELATION_LE);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cpufreq_driver_resolve_freq);
|
||||
|
||||
@@ -2357,7 +2343,6 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
|
||||
if (cpufreq_disabled())
|
||||
return -ENODEV;
|
||||
|
||||
target_freq = clamp_val(target_freq, policy->min, policy->max);
|
||||
target_freq = __resolve_freq(policy, target_freq, relation);
|
||||
|
||||
trace_android_vh_cpufreq_target(policy, &target_freq, old_target_freq);
|
||||
@@ -2684,15 +2669,11 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,
|
||||
* Resolve policy min/max to available frequencies. It ensures
|
||||
* no frequency resolution will neither overshoot the requested maximum
|
||||
* nor undershoot the requested minimum.
|
||||
*
|
||||
* Avoid storing intermediate values in policy->max or policy->min and
|
||||
* compiler optimizations around them because they may be accessed
|
||||
* concurrently by cpufreq_driver_resolve_freq() during the update.
|
||||
*/
|
||||
WRITE_ONCE(policy->max, __resolve_freq(policy, new_data.max, CPUFREQ_RELATION_H));
|
||||
new_data.min = __resolve_freq(policy, new_data.min, CPUFREQ_RELATION_L);
|
||||
WRITE_ONCE(policy->min, new_data.min > policy->max ? policy->max : new_data.min);
|
||||
|
||||
policy->min = new_data.min;
|
||||
policy->max = new_data.max;
|
||||
policy->min = __resolve_freq(policy, policy->min, CPUFREQ_RELATION_L);
|
||||
policy->max = __resolve_freq(policy, policy->max, CPUFREQ_RELATION_H);
|
||||
trace_cpu_frequency_limits(policy);
|
||||
|
||||
cpufreq_update_pressure(policy);
|
||||
|
||||
Reference in New Issue
Block a user