X-Git-Url: http://nv-tegra.nvidia.com/gitweb/?p=linux-3.10.git;a=blobdiff_plain;f=kernel%2Frcupdate.c;h=48d3bce465b88e38b0715a46a5b7fe8c95820c2d;hp=f45b91723dc65f6ba177e4034ef67b2fbacbd5e5;hb=c3f5902325d3053986e7359f706581d8f032e72f;hpb=89d46b8778f65223f732d82c0166e0abba20fb1e diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index f45b917..48d3bce 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c @@ -257,15 +257,23 @@ static void rcu_start_batch(struct rcu_ctrlblk *rcp, struct rcu_state *rsp, if (rcp->next_pending && 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; - /* 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(); 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); + } }