diff options
author | Viresh Kumar <viresh.kumar@linaro.org> | 2019-06-19 23:05:50 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2019-06-28 05:24:56 -0400 |
commit | 70a59fde6e69d1d8579f84bf4555bfffb3ce452d (patch) | |
tree | 53863dd8106c2f2a564da43055a3e1154da2895f /drivers/cpufreq | |
parent | 5980752e6ef7079c0839576df10f8062d8a48883 (diff) |
cpufreq: Avoid calling cpufreq_verify_current_freq() from handle_update()
On some occasions cpufreq_verify_current_freq() schedules a work whose
callback is handle_update(), which further calls cpufreq_update_policy()
which may end up calling cpufreq_verify_current_freq() again.
On the other hand, when cpufreq_update_policy() is called from
handle_update(), the pointer to the cpufreq policy is already
available, but cpufreq_cpu_acquire() is still called to get it in
cpufreq_update_policy(), which should be avoided as well.
To fix these issues, create a new helper, refresh_frequency_limits(),
and make both handle_update() call it cpufreq_update_policy().
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
[ rjw: Rename reeval_frequency_limits() as refresh_frequency_limits() ]
[ rjw: Changelog ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/cpufreq')
-rw-r--r-- | drivers/cpufreq/cpufreq.c | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index cba9c9e1bd0f..ceb57af15ca0 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -1115,13 +1115,25 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, unsigned int cp | |||
1115 | return ret; | 1115 | return ret; |
1116 | } | 1116 | } |
1117 | 1117 | ||
1118 | static void refresh_frequency_limits(struct cpufreq_policy *policy) | ||
1119 | { | ||
1120 | struct cpufreq_policy new_policy = *policy; | ||
1121 | |||
1122 | pr_debug("updating policy for CPU %u\n", policy->cpu); | ||
1123 | |||
1124 | new_policy.min = policy->user_policy.min; | ||
1125 | new_policy.max = policy->user_policy.max; | ||
1126 | |||
1127 | cpufreq_set_policy(policy, &new_policy); | ||
1128 | } | ||
1129 | |||
1118 | static void handle_update(struct work_struct *work) | 1130 | static void handle_update(struct work_struct *work) |
1119 | { | 1131 | { |
1120 | struct cpufreq_policy *policy = | 1132 | struct cpufreq_policy *policy = |
1121 | container_of(work, struct cpufreq_policy, update); | 1133 | container_of(work, struct cpufreq_policy, update); |
1122 | unsigned int cpu = policy->cpu; | 1134 | |
1123 | pr_debug("handle_update for cpu %u called\n", cpu); | 1135 | pr_debug("handle_update for cpu %u called\n", policy->cpu); |
1124 | cpufreq_update_policy(cpu); | 1136 | refresh_frequency_limits(policy); |
1125 | } | 1137 | } |
1126 | 1138 | ||
1127 | static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu) | 1139 | static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu) |
@@ -2376,7 +2388,6 @@ int cpufreq_set_policy(struct cpufreq_policy *policy, | |||
2376 | void cpufreq_update_policy(unsigned int cpu) | 2388 | void cpufreq_update_policy(unsigned int cpu) |
2377 | { | 2389 | { |
2378 | struct cpufreq_policy *policy = cpufreq_cpu_acquire(cpu); | 2390 | struct cpufreq_policy *policy = cpufreq_cpu_acquire(cpu); |
2379 | struct cpufreq_policy new_policy; | ||
2380 | 2391 | ||
2381 | if (!policy) | 2392 | if (!policy) |
2382 | return; | 2393 | return; |
@@ -2389,12 +2400,7 @@ void cpufreq_update_policy(unsigned int cpu) | |||
2389 | (cpufreq_suspended || WARN_ON(!cpufreq_verify_current_freq(policy, false)))) | 2400 | (cpufreq_suspended || WARN_ON(!cpufreq_verify_current_freq(policy, false)))) |
2390 | goto unlock; | 2401 | goto unlock; |
2391 | 2402 | ||
2392 | pr_debug("updating policy for CPU %u\n", cpu); | 2403 | refresh_frequency_limits(policy); |
2393 | memcpy(&new_policy, policy, sizeof(*policy)); | ||
2394 | new_policy.min = policy->user_policy.min; | ||
2395 | new_policy.max = policy->user_policy.max; | ||
2396 | |||
2397 | cpufreq_set_policy(policy, &new_policy); | ||
2398 | 2404 | ||
2399 | unlock: | 2405 | unlock: |
2400 | cpufreq_cpu_release(policy); | 2406 | cpufreq_cpu_release(policy); |