rcu: Fix bug in rcu_barrier() torture test
authorPaul E. McKenney <paul.mckenney@linaro.org>
Tue, 29 May 2012 02:21:41 +0000 (19:21 -0700)
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Mon, 2 Jul 2012 19:34:03 +0000 (12:34 -0700)
commitc6ebcbb60c8c68a88160fe54302e851700d1362c
treed95b0c10d7107d3d34a108aa75222820157fd599
parente3f8d3788ed7cf55946030dc9b76e73edb111602
rcu: Fix bug in rcu_barrier() torture test

The child threads in the rcu_torture_barrier_cbs() are improperly
synchronized, which can cause the rcu_barrier() tests to hang.  The
failure mode is as follows:

1. CPU 0 running in rcu_torture_barrier() sets barrier_cbs_count
     to n_barrier_cbs.

2. CPU 1 running in rcu_torture_barrier_cbs() wakes up, posts
     its RCU callback, and atomically decrements barrier_cbs_count.
     Because barrier_cbs_count is not zero, it does not do the wake_up().

3. CPU 2 running in rcu_torture_barrier_cbs() wakes up, but
     finds that barrier_cbs_count is not equal to n_barrier_cbs,
     and so returns to sleep.

4. The value of barrier_cbs_count therefore never reaches zero,
     which causes the test to hang.

This commit therefore uses a phase variable to coordinate the test,
preventing this scenario from occurring.

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