[PATCH 07/19] srcutree: Disable preemption across synchronize_srcu_atomic()

From: Paul E. McKenney

Date: Fri Sep 18 2026 - 20:37:58 EST


Because synchronize_srcu_atomic() cannot sleep, if a pair of them run
concurrently pinned to the same CPU, it is possible that one will spin
uselessly waiting for the other while at the same time preventing that
other from running. This commit therefore disables preemption to prevent
this failure mode.

Signed-off-by: Paul E. McKenney <paulmck@xxxxxxxxxx>
---
kernel/rcu/srcutree.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c
index 570d068d1840..61c2375ba2ec 100644
--- a/kernel/rcu/srcutree.c
+++ b/kernel/rcu/srcutree.c
@@ -2123,11 +2123,14 @@ void synchronize_srcu_atomic(struct srcu_struct *ssp)

// Perhaps others will do our work for us.
srcu_state = get_state_synchronize_srcu(ssp);
+ preempt_disable();
while (atomic_read(&sup->srcu_atomic_gp_flag) ||
atomic_xchg(&sup->srcu_atomic_gp_flag, 1)) {
+ preempt_enable();
if (poll_state_synchronize_srcu(ssp, srcu_state))
return;
cpu_relax();
+ preempt_disable();
}

// One last check for others doing our work for us under the lock.
@@ -2135,6 +2138,7 @@ void synchronize_srcu_atomic(struct srcu_struct *ssp)
if (poll_state_synchronize_srcu(ssp, srcu_state)) {
raw_spin_unlock_irq_rcu_node(sup);
atomic_set(&sup->srcu_atomic_gp_flag, 0);
+ preempt_enable();
return;
}

@@ -2152,6 +2156,7 @@ void synchronize_srcu_atomic(struct srcu_struct *ssp)
}
ASSERT_EXCLUSIVE_WRITER(sup->srcu_atomic_gp_flag);
atomic_set_release(&sup->srcu_atomic_gp_flag, 0);
+ preempt_enable();
non_block_end();
}
EXPORT_SYMBOL_GPL(synchronize_srcu_atomic);
--
2.40.1