aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTodd Poynor2012-12-20 17:51:00 -0600
committerArve Hjønnevåg2013-02-19 19:56:10 -0600
commit75cf0d0366245482c96d577bb0105329272ff6a3 (patch)
tree382bb6bbdd55358f18f05de8aebaac59ead2eefe
parenta04276770ecffcec07178c74df30687a7dedf7dc (diff)
downloadkernel-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.c6
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 /*