From bfb96b98d1400c4c7ae6994ee7ae6471c6311d85 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Fri, 25 Jan 2008 21:08:24 +0100 Subject: [PATCH] --- yaml --- r: 76168 b: refs/heads/master c: e0ecfa7917cafe72f4a75f87e8bb5d8d51dc534f h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/kernel/rcuclassic.c | 2 +- trunk/kernel/rcupdate.c | 10 ++++++++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index 991897780d99..a296ca024f54 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 01c1c660f4b8086cad7a62345fd04290f3d82c8f +refs/heads/master: e0ecfa7917cafe72f4a75f87e8bb5d8d51dc534f diff --git a/trunk/kernel/rcuclassic.c b/trunk/kernel/rcuclassic.c index 18369e3386e2..ce0cf16cab67 100644 --- a/trunk/kernel/rcuclassic.c +++ b/trunk/kernel/rcuclassic.c @@ -371,9 +371,9 @@ static void __rcu_offline_cpu(struct rcu_data *this_rdp, if (rcp->cur != rcp->completed) cpu_quiet(rdp->cpu, rcp); spin_unlock_bh(&rcp->lock); + rcu_move_batch(this_rdp, rdp->donelist, rdp->donetail); rcu_move_batch(this_rdp, rdp->curlist, rdp->curtail); rcu_move_batch(this_rdp, rdp->nxtlist, rdp->nxttail); - rcu_move_batch(this_rdp, rdp->donelist, rdp->donetail); } static void rcu_offline_cpu(int cpu) diff --git a/trunk/kernel/rcupdate.c b/trunk/kernel/rcupdate.c index 0ccd0095ebdc..760dfc233a00 100644 --- a/trunk/kernel/rcupdate.c +++ b/trunk/kernel/rcupdate.c @@ -115,7 +115,17 @@ void rcu_barrier(void) mutex_lock(&rcu_barrier_mutex); init_completion(&rcu_barrier_completion); atomic_set(&rcu_barrier_cpu_count, 0); + /* + * The queueing of callbacks in all CPUs must be atomic with + * respect to RCU, otherwise one CPU may queue a callback, + * wait for a grace period, decrement barrier count and call + * complete(), while other CPUs have not yet queued anything. + * So, we need to make sure that grace periods cannot complete + * until all the callbacks are queued. + */ + rcu_read_lock(); on_each_cpu(rcu_barrier_func, NULL, 0, 1); + rcu_read_unlock(); wait_for_completion(&rcu_barrier_completion); mutex_unlock(&rcu_barrier_mutex); }