From a4524d29de6d348bbb29379a417b4d23a9492b33 Mon Sep 17 00:00:00 2001 From: Liang Chen Date: Wed, 18 Dec 2019 20:16:15 +0800 Subject: [PATCH] cpufreq: interactive: fix race between input event and governor exit The input event callback does not check the governor_enabled state on affected CPUS, which will cause kernel panic because the governor_data will be NULL when governor exit. Change-Id: Ic2e5cdaefa519701b23203bb77804ce850a5d349 Signed-off-by: Liang Chen --- drivers/cpufreq/cpufreq_interactive.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c index a8ecd8a6a93a..b60edc2d2d36 100644 --- a/drivers/cpufreq/cpufreq_interactive.c +++ b/drivers/cpufreq/cpufreq_interactive.c @@ -1125,20 +1125,34 @@ static void cpufreq_interactive_input_event(struct input_handle *handle, now = ktime_to_us(ktime_get()); for_each_online_cpu(i) { pcpu = &per_cpu(cpuinfo, i); - if (!pcpu->policy) + if (!down_read_trylock(&pcpu->enable_sem)) continue; + if (!pcpu->governor_enabled) { + up_read(&pcpu->enable_sem); + continue; + } + + if (!pcpu->policy) { + up_read(&pcpu->enable_sem); + continue; + } + if (have_governor_per_policy()) tunables = pcpu->policy->governor_data; else tunables = common_tunables; - if (!tunables) + if (!tunables) { + up_read(&pcpu->enable_sem); continue; + } endtime = now + tunables->touchboostpulse_duration_val; if (endtime < (tunables->touchboostpulse_endtime + - 10 * USEC_PER_MSEC)) + 10 * USEC_PER_MSEC)) { + up_read(&pcpu->enable_sem); continue; + } tunables->touchboostpulse_endtime = endtime; spin_lock_irqsave(&pcpu->target_freq_lock, flags[1]); @@ -1421,6 +1435,7 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy, pcpu = &per_cpu(cpuinfo, j); down_write(&pcpu->enable_sem); pcpu->governor_enabled = 0; + pcpu->policy = NULL; del_timer_sync(&pcpu->cpu_timer); del_timer_sync(&pcpu->cpu_slack_timer); up_write(&pcpu->enable_sem);