]>
Commit | Line | Data |
---|---|---|
5aad64fa GKH |
1 | From fd7de1e8d5b2b2b35e71332fafb899f584597150 Mon Sep 17 00:00:00 2001 |
2 | From: Andy Lutomirski <luto@amacapital.net> | |
3 | Date: Sat, 29 Nov 2014 08:13:51 -0800 | |
4 | Subject: sched: Add missing rcu protection to wake_up_all_idle_cpus | |
5 | ||
6 | From: Andy Lutomirski <luto@amacapital.net> | |
7 | ||
8 | commit fd7de1e8d5b2b2b35e71332fafb899f584597150 upstream. | |
9 | ||
10 | Locklessly doing is_idle_task(rq->curr) is only okay because of | |
11 | RCU protection. The older variant of the broken code checked | |
12 | rq->curr == rq->idle instead and therefore didn't need RCU. | |
13 | ||
14 | Fixes: f6be8af1c95d ("sched: Add new API wake_up_if_idle() to wake up the idle cpu") | |
15 | Signed-off-by: Andy Lutomirski <luto@amacapital.net> | |
16 | Reviewed-by: Chuansheng Liu <chuansheng.liu@intel.com> | |
17 | Cc: Peter Zijlstra <peterz@infradead.org> | |
18 | Link: http://lkml.kernel.org/r/729365dddca178506dfd0a9451006344cd6808bc.1417277372.git.luto@amacapital.net | |
19 | Signed-off-by: Ingo Molnar <mingo@kernel.org> | |
20 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
21 | ||
22 | --- | |
23 | kernel/sched/core.c | 9 +++++++-- | |
24 | 1 file changed, 7 insertions(+), 2 deletions(-) | |
25 | ||
26 | --- a/kernel/sched/core.c | |
27 | +++ b/kernel/sched/core.c | |
28 | @@ -1623,8 +1623,10 @@ void wake_up_if_idle(int cpu) | |
29 | struct rq *rq = cpu_rq(cpu); | |
30 | unsigned long flags; | |
31 | ||
32 | - if (!is_idle_task(rq->curr)) | |
33 | - return; | |
34 | + rcu_read_lock(); | |
35 | + | |
36 | + if (!is_idle_task(rcu_dereference(rq->curr))) | |
37 | + goto out; | |
38 | ||
39 | if (set_nr_if_polling(rq->idle)) { | |
40 | trace_sched_wake_idle_without_ipi(cpu); | |
41 | @@ -1635,6 +1637,9 @@ void wake_up_if_idle(int cpu) | |
42 | /* Else cpu is not in idle, do nothing here */ | |
43 | raw_spin_unlock_irqrestore(&rq->lock, flags); | |
44 | } | |
45 | + | |
46 | +out: | |
47 | + rcu_read_unlock(); | |
48 | } | |
49 | ||
50 | bool cpus_share_cache(int this_cpu, int that_cpu) |