]> git.karo-electronics.de Git - karo-tx-linux.git/commit
rcu: Prevent initialization-time quiescent-state race
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Fri, 6 Jul 2012 18:18:51 +0000 (11:18 -0700)
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Mon, 23 Jul 2012 15:30:25 +0000 (08:30 -0700)
commit289ff2b6d0150852c1ed34555f5a11b7b8a8baed
tree62b1db8a59862c0b4f0b2b555c3ffdba0d4385bf
parent2e290b6fc405470adc2adb57eb355a88b26154eb
rcu: Prevent initialization-time quiescent-state race

Now the the grace-period initialization procedure is preemptible, it is
subject to the following race on systems whose rcu_node tree contains
more than one node:

1. CPU 31 starts initializing the grace period, including the
first leaf rcu_node structures, and is then preempted.

2. CPU 0 refers to the first leaf rcu_node structure, and notes
that a new grace period has started.  It passes through a
quiescent state shortly thereafter, and informs the RCU core
of this rite of passage.

3. CPU 0 enters an RCU read-side critical section, acquiring
a pointer to an RCU-protected data item.

4. CPU 31 removes the data item referenced by CPU 0 from the
data structure, and registers an RCU callback in order to
free it.

5. CPU 31 resumes initializing the grace period, including its
own rcu_node structure.  In invokes rcu_start_gp_per_cpu(),
which advances all callbacks, including the one registered
in #4 above, to be handled by the current grace period.

6. The remaining CPUs pass through quiescent states and inform
the RCU core, but CPU 0 remains in its RCU read-side critical
section, still referencing the now-removed data item.

7. The grace period completes and all the callbacks are invoked,
including the one that frees the data item that CPU 0 is still
referencing.  Oops!!!

This commit therefore moves the callback handling to precede initialization
of any of the rcu_node structures, thus avoiding this race.

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