From e9cb090ff7ff9430bce3e43d8e33a0354769ba8c Mon Sep 17 00:00:00 2001 From: Hanumath Prasad Date: Mon, 22 Jun 2015 16:03:57 +0530 Subject: [PATCH] cpufreq: interactive:call __cpufreq_driver_target() for cur frequency There is a race window as explained below when governor tries to change the cpu frequency and some other thread (say thermal mitigation) try to change the policy limits simultaneously. speedchange task (ThreadA) Thread B(say Thermal) cpufreq_interactive_speedchange_task() | __cpufreq_driver_target() | set_cpu_freq() | cpufreq_update_policy() | modified policy_max | check policy->curr against new policy limits,return without calling __cpufreq_driver_target as policy->curr(which is not updated by ThreadA) is still within the new policy limits. | sent CPUFREQ_POSTCHANGE notification | updated policy->cur which happens to be higher than policy->max This results the current frequency being higher than the policy->max and violating the policy limits. This causes thermal impact and in turn high power consumption. So Fix this by calling __cpufreq_driver_target() always with current frequency and leave it to __cpufreq_driver_target() to guarantee there is no race condition when multiple threads are changing frequencies. Change-Id: I9136e9245677e8fc90a628d3099aca8d63d3677c Signed-off-by: Hanumath Prasad --- drivers/cpufreq/cpufreq_interactive.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c index 59413e66c1b2..0abf1621e2f4 100644 --- a/drivers/cpufreq/cpufreq_interactive.c +++ b/drivers/cpufreq/cpufreq_interactive.c @@ -1656,12 +1656,8 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy, break; case CPUFREQ_GOV_LIMITS: - if (policy->max < policy->cur) - __cpufreq_driver_target(policy, - policy->max, CPUFREQ_RELATION_H); - else if (policy->min > policy->cur) - __cpufreq_driver_target(policy, - policy->min, CPUFREQ_RELATION_L); + __cpufreq_driver_target(policy, + policy->cur, CPUFREQ_RELATION_L); for_each_cpu(j, policy->cpus) { pcpu = &per_cpu(cpuinfo, j);