linux-stable/kernel/rcu
Paul E. McKenney aa24f93753 rcu: Fix rcu_barrier_callback() race condition
The rcu_barrier_callback() function does an atomic_dec_and_test(), and
if it is the last CPU to check in, does the required wakeup.  Either way,
it does an event trace.  Unfortunately, this is susceptible to the
following sequence of events:

o	CPU 0 invokes rcu_barrier_callback(), but atomic_dec_and_test()
	says that it is not last.  But at this point, CPU 0 is delayed,
	perhaps due to an NMI, SMI, or vCPU preemption.

o	CPU 1 invokes rcu_barrier_callback(), and atomic_dec_and_test()
	says that it is last.  So CPU 1 traces completion and does
	the needed wakeup.

o	The awakened rcu_barrier() function does cleanup and releases
	rcu_state.barrier_mutex.

o	Another CPU now acquires rcu_state.barrier_mutex and starts
	another round of rcu_barrier() processing, including updating
	rcu_state.barrier_sequence.

o	CPU 0 gets its act back together and does its tracing.  Except
	that rcu_state.barrier_sequence has already been updated, so
	its tracing is incorrect and probably quite confusing.
	(Wait!  Why did this CPU check in twice for one rcu_barrier()
	invocation???)

This commit therefore causes rcu_barrier_callback() to take a
snapshot of the value of rcu_state.barrier_sequence before invoking
atomic_dec_and_test(), thus guaranteeing that the event-trace output
is sensible, even if the timing of the event-trace output might still
be confusing.  (Wait!  Why did the old rcu_barrier() complete before
all of its CPUs checked in???)  But being that this is RCU, only so much
confusion can reasonably be eliminated.

This data race was reported by KCSAN.  Not appropriate for backporting
due to failure being unlikely and due to the mild consequences of the
failure, namely a confusing event trace.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
2020-02-20 15:58:23 -08:00
..
Kconfig rcu: Use CONFIG_PREEMPTION where appropriate 2019-12-09 12:37:51 -08:00
Kconfig.debug rcu: Add support for consolidated-RCU reader checking 2019-08-09 11:00:35 -07:00
Makefile rcu: Provide debug symbols and line numbers in KCSAN runs 2020-02-20 15:58:21 -08:00
rcu.h rcu: Warn on for_each_leaf_node_cpu_mask() from non-leaf 2020-02-20 15:58:21 -08:00
rcu_segcblist.c rcu: Remove dead code from rcu_segcblist_insert_pend_cbs() 2020-02-20 15:58:23 -08:00
rcu_segcblist.h rcu: Remove kfree_rcu() special casing and lazy-callback handling 2020-01-24 10:24:31 -08:00
rcuperf.c rcu: Remove kfree_call_rcu_nobatch() 2020-01-24 10:24:31 -08:00
rcutorture.c Merge branches 'doc.2019.12.10a', 'exp.2019.12.09a', 'fixes.2020.01.24a', 'kfree_rcu.2020.01.24a', 'list.2020.01.10a', 'preempt.2020.01.24a' and 'torture.2019.12.09a' into HEAD 2020-01-24 10:37:27 -08:00
srcutiny.c rcu: Use CONFIG_PREEMPTION where appropriate 2019-12-09 12:37:51 -08:00
srcutree.c rcu: Fix typos in file-header comments 2020-02-20 15:58:22 -08:00
sync.c rcu/sync: Simplify the state machine 2019-05-28 09:05:23 -07:00
tiny.c rcu: Remove kfree_rcu() special casing and lazy-callback handling 2020-01-24 10:24:31 -08:00
tree.c rcu: Fix rcu_barrier_callback() race condition 2020-02-20 15:58:23 -08:00
tree.h Merge branches 'doc.2019.12.10a', 'exp.2019.12.09a', 'fixes.2020.01.24a', 'kfree_rcu.2020.01.24a', 'list.2020.01.10a', 'preempt.2020.01.24a' and 'torture.2019.12.09a' into HEAD 2020-01-24 10:37:27 -08:00
tree_exp.h rcu: Add WRITE_ONCE to rcu_node ->exp_seq_rq store 2020-02-20 15:58:22 -08:00
tree_plugin.h rcu: Add *_ONCE() to rcu_node ->boost_kthread_status 2020-02-20 15:58:22 -08:00
tree_stall.h rcu: Add WRITE_ONCE() to rcu_state ->gp_start 2020-02-20 15:58:23 -08:00
update.c Merge branches 'doc.2019.12.10a', 'exp.2019.12.09a', 'fixes.2020.01.24a', 'kfree_rcu.2020.01.24a', 'list.2020.01.10a', 'preempt.2020.01.24a' and 'torture.2019.12.09a' into HEAD 2020-01-24 10:37:27 -08:00