From 1978d531940fc617ba899612da6671b457a512e4 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Mon, 12 May 2008 21:21:05 +0200 Subject: [PATCH] --- yaml --- r: 101363 b: refs/heads/master c: 8db559b83009bed92e1b5dd13a651ff273d9ff62 h: refs/heads/master i: 101361: 7a792ec5e937fb70d1d00bf861d43cfeec1ad1e1 101359: b50add9f094693afc2ea4b72fbdbf4ce523bfa46 v: v3 --- [refs] | 2 +- trunk/kernel/rcuclassic.c | 30 +++++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index fb1f6fe4c4bf..c4a64c075919 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 4446a36ff8c74ac3b32feb009b651048e129c6af +refs/heads/master: 8db559b83009bed92e1b5dd13a651ff273d9ff62 diff --git a/trunk/kernel/rcuclassic.c b/trunk/kernel/rcuclassic.c index f4ffbd0f306f..d8348792f9f5 100644 --- a/trunk/kernel/rcuclassic.c +++ b/trunk/kernel/rcuclassic.c @@ -502,10 +502,38 @@ void rcu_check_callbacks(int cpu, int user) if (user || (idle_cpu(cpu) && !in_softirq() && hardirq_count() <= (1 << HARDIRQ_SHIFT))) { + + /* + * Get here if this CPU took its interrupt from user + * mode or from the idle loop, and if this is not a + * nested interrupt. In this case, the CPU is in + * a quiescent state, so count it. + * + * Also do a memory barrier. This is needed to handle + * the case where writes from a preempt-disable section + * of code get reordered into schedule() by this CPU's + * write buffer. The memory barrier makes sure that + * the rcu_qsctr_inc() and rcu_bh_qsctr_inc() are see + * by other CPUs to happen after any such write. + */ + + smp_mb(); /* See above block comment. */ rcu_qsctr_inc(cpu); rcu_bh_qsctr_inc(cpu); - } else if (!in_softirq()) + + } else if (!in_softirq()) { + + /* + * Get here if this CPU did not take its interrupt from + * softirq, in other words, if it is not interrupting + * a rcu_bh read-side critical section. This is an _bh + * critical section, so count it. The memory barrier + * is needed for the same reason as is the above one. + */ + + smp_mb(); /* See above block comment. */ rcu_bh_qsctr_inc(cpu); + } raise_rcu_softirq(); }