aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@linaro.org>2019-06-19 23:05:50 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2019-06-28 05:24:56 -0400
commit70a59fde6e69d1d8579f84bf4555bfffb3ce452d (patch)
tree53863dd8106c2f2a564da43055a3e1154da2895f /drivers/cpufreq
parent5980752e6ef7079c0839576df10f8062d8a48883 (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.c26
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
1118static 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
1118static void handle_update(struct work_struct *work) 1130static 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
1127static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu) 1139static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu)
@@ -2376,7 +2388,6 @@ int cpufreq_set_policy(struct cpufreq_policy *policy,
2376void cpufreq_update_policy(unsigned int cpu) 2388void 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
2399unlock: 2405unlock:
2400 cpufreq_cpu_release(policy); 2406 cpufreq_cpu_release(policy);