On Sun, Oct 4, 2026 at 8:33 AM Joel Fernandes <[email protected]> wrote:
>
> On 10/3/2026 12:17 PM, Kunwu Chan wrote:
> > Add support for scaling atomic SRCU grace periods using
> > srcu_read_lock_atomic()/srcu_read_unlock_atomic() and
> > synchronize_srcu_atomic().
> >
> > Suggested-by: Paul E. McKenney <[email protected]>
> > Signed-off-by: Kunwu Chan <[email protected]>
> > ---
> > Changes since v1:
> > - Rename srcu_atomic_ctlp to srcua and reuse srcu_ctlp for
> >   SRCU operations, as suggested by Paul.
> > - Reuse the existing SRCU cleanup and completed helpers by
> >   initializing srcu_ctlp in srcu_atomic_scale_init().
> > - Add .stats using srcu_scale_stats().
> > - Use "srcua" to match the existing "srcu" and "srcud" scale
> >   type names.
> > - Use synchronize_srcu_atomic() for both normal and expedited
> >   scale tests.
> >
> > v1: 
> > https://lore.kernel.org/all/[email protected]/
> > Tested with kvm.sh --torture rcuscale scale_type=srcua on x86_64 and
> > arm64, alongside gp_exp=1 and PROVE_LOCKING=y: no warnings or lockdep
> > splats.
> > ---
>
> Maybe some performance numbers too for an rcuscale patch? ;-) But either way:
>
> Reviewed-by: Joel Fernandes <[email protected]>

Thanks Joel for the review!

Here are the rcuscale numbers. All tests were run with
kvm.sh --torture rcuscale using scale_type=srcua on 12-CPU
x86_64 and 256-CPU arm64 KVM guests, with and without
PROVE_LOCKING.

All values below are synchronize_srcu_atomic() durations:

  Arch    CPUs  lockdep  gp_exp  median   P99      max
  x86_64   12      n        0    0.82us   1.57us    864us
  x86_64   12      n        1    0.87us   1.54us    857us
  x86_64   12      y        0    0.72us   0.93us     11us
  x86_64   12      y        1    0.66us   0.85us    160us
  arm64   256      n        0   26.2us   71.2us   3389us
  arm64   256      n        1   24.3us   60.6us  10513us
  arm64   256      y        0   13.4us   43.6us   4066us
  arm64   256      y        1    8.86us  22.6us   8004us

gp_exp=1 does not significantly change the distribution for
srcua, since there is no separate expedited primitive for
atomic SRCU.

For comparison, synchronize_srcu() on the same arm64 guest
takes about 8ms under the same workload.

All runs completed without warnings, lockdep splats, or shutdown
issues.

Thanks,
Kunwu

>
>
>
>
>
> >  kernel/rcu/rcuscale.c | 41 ++++++++++++++++++++++++++++++++++++++++-
> >  1 file changed, 40 insertions(+), 1 deletion(-)
> >
> > diff --git a/kernel/rcu/rcuscale.c b/kernel/rcu/rcuscale.c
> > index 1097ec15879c..b172882824ac 100644
> > --- a/kernel/rcu/rcuscale.c
> > +++ b/kernel/rcu/rcuscale.c
> > @@ -293,6 +293,44 @@ static struct rcu_scale_ops srcud_ops = {
> >       .name           = "srcud"
> >  };
> >
> > +static struct srcu_struct srcua;
> > +
> > +static int srcu_scale_atomic_read_lock(void)
> > +{
> > +     return srcu_read_lock_atomic(srcu_ctlp);
> > +}
> > +
> > +static void srcu_scale_atomic_read_unlock(int idx)
> > +{
> > +     srcu_read_unlock_atomic(srcu_ctlp, idx);
> > +}
> > +
> > +static void srcu_scale_atomic_synchronize(void)
> > +{
> > +     synchronize_srcu_atomic(srcu_ctlp);
> > +}
> > +
> > +static void srcu_atomic_scale_init(void)
> > +{
> > +     srcu_ctlp = &srcua;
> > +     init_srcu_struct_atomic(srcu_ctlp);
> > +}
> > +
> > +static struct rcu_scale_ops srcua_ops = {
> > +     .ptype          = SRCU_FLAVOR,
> > +     .init           = srcu_atomic_scale_init,
> > +     .cleanup        = srcu_sync_scale_cleanup,
> > +     .readlock       = srcu_scale_atomic_read_lock,
> > +     .readunlock     = srcu_scale_atomic_read_unlock,
> > +     .get_gp_seq     = srcu_scale_completed,
> > +     .gp_diff        = rcu_seq_diff,
> > +     .exp_completed  = srcu_scale_completed,
> > +     .sync           = srcu_scale_atomic_synchronize,
> > +     .exp_sync       = srcu_scale_atomic_synchronize,
> > +     .stats          = srcu_scale_stats,
> > +     .name           = "srcua"
> > +};
> > +
> >  #ifdef CONFIG_TASKS_RCU
> >
> >  /*
> > @@ -1110,7 +1148,8 @@ rcu_scale_init(void)
> >       long i;
> >       long j;
> >       static struct rcu_scale_ops *scale_ops[] = {
> > -             &rcu_ops, &srcu_ops, &srcud_ops, TASKS_OPS TASKS_RUDE_OPS 
> > TASKS_TRACING_OPS
> > +             &rcu_ops, &srcu_ops, &srcua_ops, &srcud_ops,
> > +             TASKS_OPS TASKS_RUDE_OPS TASKS_TRACING_OPS
> >       };
> >
> >       if (!torture_init_begin(scale_type, verbose))
> >
> > base-commit: d21906b0aa1e9573cdb5e7acaca44966b9d1dcd2
>
> --
> Joel Fernandes
>

Reply via email to