rcu_sync->gp_count is updated under the protection of ->rss_lock but read locklessly by the WARN_ON() checks, and KCSAN noted the data race. Move these WARN_ON_ONCE()'s under the lock and remove the no longer needed READ_ONCE(). Reported-by: "Paul E. McKenney" <paulmck@xxxxxxxxxx> Signed-off-by: Oleg Nesterov <oleg@xxxxxxxxxx> --- kernel/rcu/sync.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/rcu/sync.c b/kernel/rcu/sync.c index 86df878a2fee..b50fde082198 100644 --- a/kernel/rcu/sync.c +++ b/kernel/rcu/sync.c @@ -152,9 +152,9 @@ void rcu_sync_enter(struct rcu_sync *rsp) void rcu_sync_exit(struct rcu_sync *rsp) { WARN_ON_ONCE(READ_ONCE(rsp->gp_state) == GP_IDLE); - WARN_ON_ONCE(READ_ONCE(rsp->gp_count) == 0); spin_lock_irq(&rsp->rss_lock); + WARN_ON_ONCE(rsp->gp_count == 0); if (!--rsp->gp_count) { if (rsp->gp_state == GP_PASSED) { WRITE_ONCE(rsp->gp_state, GP_EXIT); @@ -174,10 +174,10 @@ void rcu_sync_dtor(struct rcu_sync *rsp) { int gp_state; - WARN_ON_ONCE(READ_ONCE(rsp->gp_count)); WARN_ON_ONCE(READ_ONCE(rsp->gp_state) == GP_PASSED); spin_lock_irq(&rsp->rss_lock); + WARN_ON_ONCE(rsp->gp_count != 0); if (rsp->gp_state == GP_REPLAY) WRITE_ONCE(rsp->gp_state, GP_EXIT); gp_state = rsp->gp_state; -- 2.25.1.362.g51ebf55