mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
cpufreq: Avoid redundant target() calls for unchanged limits
Drivers setting CPUFREQ_NEED_UPDATE_LIMITS expect target() to be invoked even if the target frequency remains unchanged, so they can update their internal policy limits state. Currently the core invokes target() unconditionally whenever the requested frequency matches policy->cur for such drivers, even if policy->min and policy->max haven't changed since the previous update. Track pending policy limit updates explicitly and skip redundant target() invocations when neither the target frequency nor the effective limits changed. Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Reviewed-by: Lifeng Zheng <zhenglifeng1@huawei.com> Reviewed-by: Zhongqiu Han <zhongqiu.han@oss.qualcomm.com> Link: https://patch.msgid.link/d0107c364b709abca21acf88072220bc05478594.1779423281.git.viresh.kumar@linaro.org Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
parent
aa70232cc7
commit
9801be8bef
|
|
@ -2368,9 +2368,13 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
|
|||
* exactly same freq is called again and so we can save on few function
|
||||
* calls.
|
||||
*/
|
||||
if (target_freq == policy->cur &&
|
||||
!(cpufreq_driver->flags & CPUFREQ_NEED_UPDATE_LIMITS))
|
||||
return 0;
|
||||
if (target_freq == policy->cur) {
|
||||
if (!(cpufreq_driver->flags & CPUFREQ_NEED_UPDATE_LIMITS) ||
|
||||
!policy->update_limits)
|
||||
return 0;
|
||||
|
||||
policy->update_limits = false;
|
||||
}
|
||||
|
||||
if (cpufreq_driver->target) {
|
||||
/*
|
||||
|
|
@ -2622,6 +2626,7 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,
|
|||
{
|
||||
struct cpufreq_policy_data new_data;
|
||||
struct cpufreq_governor *old_gov;
|
||||
unsigned int freq;
|
||||
int ret;
|
||||
|
||||
memcpy(&new_data.cpuinfo, &policy->cpuinfo, sizeof(policy->cpuinfo));
|
||||
|
|
@ -2654,12 +2659,20 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,
|
|||
* 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,
|
||||
new_data.min, new_data.max,
|
||||
CPUFREQ_RELATION_H));
|
||||
new_data.min = __resolve_freq(policy, new_data.min, new_data.min,
|
||||
new_data.max, CPUFREQ_RELATION_L);
|
||||
WRITE_ONCE(policy->min, new_data.min > policy->max ? policy->max : new_data.min);
|
||||
freq = __resolve_freq(policy, new_data.max, new_data.min, new_data.max,
|
||||
CPUFREQ_RELATION_H);
|
||||
if (freq != policy->max) {
|
||||
WRITE_ONCE(policy->max, freq);
|
||||
policy->update_limits = true;
|
||||
}
|
||||
|
||||
freq = __resolve_freq(policy, new_data.min, new_data.min, new_data.max,
|
||||
CPUFREQ_RELATION_L);
|
||||
freq = min(freq, policy->max);
|
||||
if (freq != policy->min) {
|
||||
WRITE_ONCE(policy->min, freq);
|
||||
policy->update_limits = true;
|
||||
}
|
||||
|
||||
trace_cpu_frequency_limits(policy);
|
||||
|
||||
|
|
|
|||
|
|
@ -146,6 +146,9 @@ struct cpufreq_policy {
|
|||
/* Per policy boost supported flag. */
|
||||
bool boost_supported;
|
||||
|
||||
/* Pending policy->min/max update for the driver */
|
||||
bool update_limits;
|
||||
|
||||
/* Cached frequency lookup from cpufreq_driver_resolve_freq. */
|
||||
unsigned int cached_target_freq;
|
||||
unsigned int cached_resolved_idx;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user