aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2011-05-19 20:09:54 -0400
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2011-05-26 12:42:19 -0400
commitba9f207c9f82115aba4ce04b22e0081af0ae300f (patch)
tree469b255f597c4910306566d038496780a16e56a2 /lib
parent80d02085d99039b3b7f3a73c8896226b0cb1ba07 (diff)
rcu: Fix unpaired rcu_irq_enter() from locking selftests
HARDIRQ_ENTER() maps to irq_enter() which calls rcu_irq_enter(). But HARDIRQ_EXIT() maps to __irq_exit() which doesn't call rcu_irq_exit(). So for every locking selftest that simulates hardirq disabled, we create an imbalance in the rcu extended quiescent state internal state. As a result, after the first missing rcu_irq_exit(), subsequent irqs won't exit dyntick-idle mode after leaving the interrupt handler. This means that RCU won't see the affected CPU as being in an extended quiescent state, resulting in long grace-period delays (as in grace periods extending for hours). To fix this, just use __irq_enter() to simulate the hardirq context. This is sufficient for the locking selftests as we don't need to exit any extended quiescent state or perform any check that irqs normally do when they wake up from idle. As a side effect, this patch makes it possible to restore "rcu: Decrease memory-barrier usage based on semi-formal proof", which eventually helped finding this bug. Reported-and-tested-by: Yinghai Lu <yinghai@kernel.org> Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stable <stable@kernel.org> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/locking-selftest.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c
index 619313ed6c46..507a22fab738 100644
--- a/lib/locking-selftest.c
+++ b/lib/locking-selftest.c
@@ -144,7 +144,7 @@ static void init_shared_classes(void)
144 144
145#define HARDIRQ_ENTER() \ 145#define HARDIRQ_ENTER() \
146 local_irq_disable(); \ 146 local_irq_disable(); \
147 irq_enter(); \ 147 __irq_enter(); \
148 WARN_ON(!in_irq()); 148 WARN_ON(!in_irq());
149 149
150#define HARDIRQ_EXIT() \ 150#define HARDIRQ_EXIT() \