Commit c3f59023 authored by Srivatsa Vaddagiri's avatar Srivatsa Vaddagiri Committed by Linus Torvalds

[PATCH] Fix RCU race in access of nohz_cpu_mask

Accessing nohz_cpu_mask before incrementing rcp->cur is racy.  It can cause
tickless idle CPUs to be included in rsp->cpumask, which will extend
graceperiods unnecessarily.

Fix this race.  It has been tested using extensions to RCU torture module
that forces various CPUs to become idle.
Signed-off-by: default avatarSrivatsa Vaddagiri <vatsa@in.ibm.com>
Cc: Dipankar Sarma <dipankar@in.ibm.com>
Cc: "Paul E. McKenney" <paulmck@us.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 89d46b87
...@@ -257,15 +257,23 @@ static void rcu_start_batch(struct rcu_ctrlblk *rcp, struct rcu_state *rsp, ...@@ -257,15 +257,23 @@ static void rcu_start_batch(struct rcu_ctrlblk *rcp, struct rcu_state *rsp,
if (rcp->next_pending && if (rcp->next_pending &&
rcp->completed == rcp->cur) { rcp->completed == rcp->cur) {
/* Can't change, since spin lock held. */
cpus_andnot(rsp->cpumask, cpu_online_map, nohz_cpu_mask);
rcp->next_pending = 0; rcp->next_pending = 0;
/* next_pending == 0 must be visible in __rcu_process_callbacks() /*
* before it can see new value of cur. * next_pending == 0 must be visible in
* __rcu_process_callbacks() before it can see new value of cur.
*/ */
smp_wmb(); smp_wmb();
rcp->cur++; rcp->cur++;
/*
* Accessing nohz_cpu_mask before incrementing rcp->cur needs a
* Barrier Otherwise it can cause tickless idle CPUs to be
* included in rsp->cpumask, which will extend graceperiods
* unnecessarily.
*/
smp_mb();
cpus_andnot(rsp->cpumask, cpu_online_map, nohz_cpu_mask);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment