cpufreq: interactive: fix race on cpufreq TRANSITION notifier
authorLianwei Wang <a22439@motorola.com>
Thu, 16 May 2013 04:07:23 +0000 (12:07 +0800)
committerJohn Stultz <john.stultz@linaro.org>
Tue, 16 Feb 2016 21:52:56 +0000 (13:52 -0800)
The cpufreq TRANSTION notifier callback does not check the
governor_enabled state on affected CPUS, which will case
kernel panic in update_load because the policy object maybe
NULL or invalid when governor_enabled is false.

Change-Id: Ie0f1718124f61e2f9b5da57abc6981ada5b83908
Signed-off-by: Lianwei Wang <a22439@motorola.com>
drivers/cpufreq/cpufreq_interactive.c

index 7303f50a118098a8e37c538bb2b17f374d07c362..691923d6c868dd3c11c3a2d9bb8268906b931f56 100644 (file)
@@ -634,9 +634,19 @@ static int cpufreq_interactive_notifier(
                for_each_cpu(cpu, pcpu->policy->cpus) {
                        struct cpufreq_interactive_cpuinfo *pjcpu =
                                &per_cpu(cpuinfo, cpu);
+                       if (cpu != freq->cpu) {
+                               if (!down_read_trylock(&pjcpu->enable_sem))
+                                       continue;
+                               if (!pjcpu->governor_enabled) {
+                                       up_read(&pjcpu->enable_sem);
+                                       continue;
+                               }
+                       }
                        spin_lock_irqsave(&pjcpu->load_lock, flags);
                        update_load(cpu);
                        spin_unlock_irqrestore(&pjcpu->load_lock, flags);
+                       if (cpu != freq->cpu)
+                               up_read(&pjcpu->enable_sem);
                }
 
                up_read(&pcpu->enable_sem);