mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09:00
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 <cl@rock-chips.com>
This commit is contained in:
@@ -1125,20 +1125,34 @@ static void cpufreq_interactive_input_event(struct input_handle *handle,
|
|||||||
now = ktime_to_us(ktime_get());
|
now = ktime_to_us(ktime_get());
|
||||||
for_each_online_cpu(i) {
|
for_each_online_cpu(i) {
|
||||||
pcpu = &per_cpu(cpuinfo, i);
|
pcpu = &per_cpu(cpuinfo, i);
|
||||||
if (!pcpu->policy)
|
if (!down_read_trylock(&pcpu->enable_sem))
|
||||||
continue;
|
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())
|
if (have_governor_per_policy())
|
||||||
tunables = pcpu->policy->governor_data;
|
tunables = pcpu->policy->governor_data;
|
||||||
else
|
else
|
||||||
tunables = common_tunables;
|
tunables = common_tunables;
|
||||||
if (!tunables)
|
if (!tunables) {
|
||||||
|
up_read(&pcpu->enable_sem);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
endtime = now + tunables->touchboostpulse_duration_val;
|
endtime = now + tunables->touchboostpulse_duration_val;
|
||||||
if (endtime < (tunables->touchboostpulse_endtime +
|
if (endtime < (tunables->touchboostpulse_endtime +
|
||||||
10 * USEC_PER_MSEC))
|
10 * USEC_PER_MSEC)) {
|
||||||
|
up_read(&pcpu->enable_sem);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
tunables->touchboostpulse_endtime = endtime;
|
tunables->touchboostpulse_endtime = endtime;
|
||||||
|
|
||||||
spin_lock_irqsave(&pcpu->target_freq_lock, flags[1]);
|
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);
|
pcpu = &per_cpu(cpuinfo, j);
|
||||||
down_write(&pcpu->enable_sem);
|
down_write(&pcpu->enable_sem);
|
||||||
pcpu->governor_enabled = 0;
|
pcpu->governor_enabled = 0;
|
||||||
|
pcpu->policy = NULL;
|
||||||
del_timer_sync(&pcpu->cpu_timer);
|
del_timer_sync(&pcpu->cpu_timer);
|
||||||
del_timer_sync(&pcpu->cpu_slack_timer);
|
del_timer_sync(&pcpu->cpu_slack_timer);
|
||||||
up_write(&pcpu->enable_sem);
|
up_write(&pcpu->enable_sem);
|
||||||
|
|||||||
Reference in New Issue
Block a user