]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
rcu: Check for idle-loop entry while in RCU read-side critical section
authorPaul E. McKenney <paul.mckenney@linaro.org>
Thu, 12 Jan 2012 21:08:18 +0000 (13:08 -0800)
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Tue, 21 Feb 2012 17:03:45 +0000 (09:03 -0800)
The inner idle loop is an extended quiescent state for all flavors
of RCU, but there have been recent bug involving use of RCU read-side
primitives from within the idle loop.  Therefore, this commit enlists
lockdep-RCU to detect attempts to enter the inner idle loop while in
an RCU read-side critical section, emitting a lockdep-RCU splat if so.

Signed-off-by: Paul E. McKenney <paul.mckenney@linaro.org>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
kernel/rcutree.c

index 0569ba11e35ab6487a51ac892fabace793e5f79a..195bf1fb59ea46b7af1826b63243e6ce8ada9cbe 100644 (file)
@@ -366,6 +366,17 @@ static void rcu_idle_enter_common(struct rcu_dynticks *rdtp, long long oldval)
        atomic_inc(&rdtp->dynticks);
        smp_mb__after_atomic_inc();  /* Force ordering with next sojourn. */
        WARN_ON_ONCE(atomic_read(&rdtp->dynticks) & 0x1);
+
+       /*
+        * The idle task is not permitted to enter the idle loop while
+        * in an RCU read-side critical section.
+        */
+       rcu_lockdep_assert(!lock_is_held(&rcu_lock_map),
+                          "Illegal idle entry in RCU read-side critical section.");
+       rcu_lockdep_assert(!lock_is_held(&rcu_bh_lock_map),
+                          "Illegal idle entry in RCU-bh read-side critical section.");
+       rcu_lockdep_assert(!lock_is_held(&rcu_sched_lock_map),
+                          "Illegal idle entry in RCU-sched read-side critical section.");
 }
 
 /**