rcu-tasks: Fix IRQ read lock/unlock data race

As noted by Marco Elver:

rcu_read_lock_trace()
   ....
t->trc_reader_scp = __srcu_read_lock_fast(&rcu_tasks_trace_srcu_struct);
	<interrupt>
					rcu_read_unlock_trace()
					< ... var decls only ... >
					scp = t->trc_reader_scp;

This constitutes a data race between these two accesses to
t->trc_reader_scp.  If rcu_read_lock_trace() were to tear its store,
this value would be corrupted.

This commit therefore defers the rcu_read_lock_untrace() function's
load from t->trc_reader_scp until after it has verified that this is
the outermost rcu_read_unlock_trace().  With this change, the interrupt
handler increments and decrements t->trc_reader_nesting and does not
access t->trc_reader_scp, thus avoiding the data race.

KCSAN located this issue.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
This commit is contained in:
Paul E. McKenney 2026-07-20 08:27:59 -07:00
commit f99dc9e288