Re: [PATCH v2 7/7] rcutorture: Check an atomic SRCU wait within an RCU reader
From: Paul E. McKenney
Date: Wed Nov 11 2026 - 19:46:39 EST
On Wed, Nov 11, 2026 at 09:59:49AM -0500, Mathieu Desnoyers wrote:
> synchronize_srcu_atomic() may be called within rcu_read_lock(). It must
> then not end an RCU grace period, because its caller still holds it up.
> Tiny SRCU did end one, by calling synchronize_rcu().
>
> Check this once, when a torture type starts with atomic SRCU readers.
> Take a cookie from get_state_synchronize_rcu() within rcu_read_lock(),
> call synchronize_srcu_atomic(), and warn if
> poll_state_synchronize_rcu() then reports the cookie as completed. The
> cookie is taken within the reader, so no RCU grace period can complete
> it before rcu_read_unlock().
>
> Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@xxxxxxxxxxxx>
Reviewed-by: Paul E. McKenney <paulmck@xxxxxxxxxx>
> ---
> kernel/rcu/rcutorture.c | 21 +++++++++++++++++++++
> 1 file changed, 21 insertions(+)
>
> diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
> index 2ec461414263..d9c9ff653cb6 100644
> --- a/kernel/rcu/rcutorture.c
> +++ b/kernel/rcu/rcutorture.c
> @@ -799,6 +799,24 @@ static void srcu_torture_read_unlock_atomic(int idx)
> srcu_read_unlock_atomic_irqrestore(srcu_ctlp, idx, flags);
> }
>
> +/*
> + * Wait for an atomic SRCU grace period within an RCU reader. The wait must
> + * not end an RCU grace period: this reader still holds it up. The cookie is
> + * taken within the reader, so no RCU grace period can complete it there.
> + */
> +static void srcu_torture_check_atomic_in_rcu_reader(void)
> +{
> + unsigned long cookie;
> +
> + rcu_read_lock();
> + cookie = get_state_synchronize_rcu();
> + synchronize_srcu_atomic(srcu_ctlp);
> + WARN_ONCE(poll_state_synchronize_rcu(cookie),
> + "%s: synchronize_srcu_atomic() ended an RCU grace period within an RCU reader\n",
> + __func__);
> + rcu_read_unlock();
> +}
> +
> static void srcu_torture_init(void)
> {
> rcu_sync_torture_init();
> @@ -819,6 +837,7 @@ static void srcu_torture_init(void)
> VERBOSE_TOROUT_STRING("srcu_torture_init atomic SRCU");
> srcu_torture_init_forbidden_apis();
> srcu_torture_init_irqsave();
> + srcu_torture_check_atomic_in_rcu_reader();
> }
> }
>
> @@ -1093,6 +1112,8 @@ static void srcud_torture_init(void)
> WARN_ON(init_srcu_struct(&srcu_ctld));
> }
> srcu_ctlp = &srcu_ctld;
> + if (reader_flavor & SRCU_READ_FLAVOR_ATOMIC)
> + srcu_torture_check_atomic_in_rcu_reader();
> }
>
> static void srcu_torture_cleanup(void)
> --
> 2.47.3
>