diff options
author | Todd Poynor | 2012-12-20 17:51:00 -0600 |
---|---|---|
committer | Arve Hjønnevåg | 2013-02-19 19:56:10 -0600 |
commit | 75cf0d0366245482c96d577bb0105329272ff6a3 (patch) | |
tree | 382bb6bbdd55358f18f05de8aebaac59ead2eefe | |
parent | a04276770ecffcec07178c74df30687a7dedf7dc (diff) | |
download | kernel-common-75cf0d0366245482c96d577bb0105329272ff6a3.tar.gz kernel-common-75cf0d0366245482c96d577bb0105329272ff6a3.tar.xz kernel-common-75cf0d0366245482c96d577bb0105329272ff6a3.zip |
cpufreq: interactive: fix race on timer restart on governor start
Starting the governor, or restarting on a hotplugged-in CPU, can race
with the timer start in idle, triggering a BUG on timer already pending.
Start the timer before setting the enable flag, and use enable_sem to
protect the sequence (and ensure correct order of the update to the
enable flag). Delete any existing timer for safety.
Change-Id: Ife77cf9fe099e8fd8543224cbf148c6722c2ffb0
Reported-by: Francisco Franco <francisco.franco@cloudcar.com>
Signed-off-by: Todd Poynor <toddpoynor@google.com>
-rw-r--r-- | drivers/cpufreq/cpufreq_interactive.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c index f3d187604d9..4dc7f04391a 100644 --- a/drivers/cpufreq/cpufreq_interactive.c +++ b/drivers/cpufreq/cpufreq_interactive.c | |||
@@ -918,17 +918,17 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy, | |||
918 | ktime_to_us(ktime_get()); | 918 | ktime_to_us(ktime_get()); |
919 | pcpu->hispeed_validate_time = | 919 | pcpu->hispeed_validate_time = |
920 | pcpu->floor_validate_time; | 920 | pcpu->floor_validate_time; |
921 | pcpu->governor_enabled = 1; | 921 | down_write(&pcpu->enable_sem); |
922 | smp_wmb(); | ||
923 | expires = jiffies + usecs_to_jiffies(timer_rate); | 922 | expires = jiffies + usecs_to_jiffies(timer_rate); |
924 | pcpu->cpu_timer.expires = expires; | 923 | pcpu->cpu_timer.expires = expires; |
925 | add_timer_on(&pcpu->cpu_timer, j); | 924 | add_timer_on(&pcpu->cpu_timer, j); |
926 | |||
927 | if (timer_slack_val >= 0) { | 925 | if (timer_slack_val >= 0) { |
928 | expires += usecs_to_jiffies(timer_slack_val); | 926 | expires += usecs_to_jiffies(timer_slack_val); |
929 | pcpu->cpu_slack_timer.expires = expires; | 927 | pcpu->cpu_slack_timer.expires = expires; |
930 | add_timer_on(&pcpu->cpu_slack_timer, j); | 928 | add_timer_on(&pcpu->cpu_slack_timer, j); |
931 | } | 929 | } |
930 | pcpu->governor_enabled = 1; | ||
931 | up_write(&pcpu->enable_sem); | ||
932 | } | 932 | } |
933 | 933 | ||
934 | /* | 934 | /* |