cpufreq: cpu-boost: Fix queue_delayed_work_on() race with hotplug
Calling queue_delayed_work_on() on a CPU that's in the process of getting hotplugged out can result in that CPU infinitely looping in msm_pm_wait_cpu_shutdown(). If queue_delayed_work_on() is called after the CPU is hotplugged out, it could wake up the CPU without going through the hotplug path and cause instability. To avoid this, make sure the CPU is and stays online while queuing a work on it. Change-Id: I1b4aae3db803e476b1a7676d08f495c1f38bb154 Signed-off-by: Saravana Kannan <skannan@codeaurora.org>
This commit is contained in:
parent
df74672faf
commit
6f13a3351a
1 changed files with 13 additions and 4 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -17,6 +17,7 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/kthread.h>
|
||||
|
@ -164,9 +165,15 @@ static int boost_mig_sync_thread(void *data)
|
|||
s->boost_min = src_policy.cur;
|
||||
|
||||
/* Force policy re-evaluation to trigger adjust notifier. */
|
||||
cpufreq_update_policy(dest_cpu);
|
||||
queue_delayed_work_on(s->cpu, cpu_boost_wq,
|
||||
&s->boost_rem, msecs_to_jiffies(boost_ms));
|
||||
get_online_cpus();
|
||||
if (cpu_online(dest_cpu)) {
|
||||
cpufreq_update_policy(dest_cpu);
|
||||
queue_delayed_work_on(dest_cpu, cpu_boost_wq,
|
||||
&s->boost_rem, msecs_to_jiffies(boost_ms));
|
||||
} else {
|
||||
s->boost_min = 0;
|
||||
}
|
||||
put_online_cpus();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -205,6 +212,7 @@ static void do_input_boost(struct work_struct *work)
|
|||
struct cpu_sync *i_sync_info;
|
||||
struct cpufreq_policy policy;
|
||||
|
||||
get_online_cpus();
|
||||
for_each_online_cpu(i) {
|
||||
|
||||
i_sync_info = &per_cpu(sync_info, i);
|
||||
|
@ -221,6 +229,7 @@ static void do_input_boost(struct work_struct *work)
|
|||
&i_sync_info->input_boost_rem,
|
||||
msecs_to_jiffies(input_boost_ms));
|
||||
}
|
||||
put_online_cpus();
|
||||
}
|
||||
|
||||
static void cpuboost_input_event(struct input_handle *handle,
|
||||
|
|
Loading…
Add table
Reference in a new issue