On Wed, Sep 9, 2026 at 3:26 PM Harry Yoo <[email protected]> wrote:
>
> On Mon, Aug 10, 2026 at 05:27:50AM -0700, Puranjay Mohan wrote:
> > ---
> >  kernel/rcu/Kconfig |   6 +++
> >  kernel/rcu/rcu.h   |  11 ++++
> >  kernel/rcu/tree.c  | 131 +++++++++++++++++++++++++++++++++++++++++----
> >  kernel/rcu/tree.h  |   6 +++
> >  4 files changed, 143 insertions(+), 11 deletions(-)
> >
> > diff --git a/kernel/rcu/Kconfig b/kernel/rcu/Kconfig
> > index f15da8038d0ba..1a5fb3156c062 100644
> > --- a/kernel/rcu/Kconfig
> > +++ b/kernel/rcu/Kconfig
> > @@ -175,6 +175,12 @@ config RCU_STALL_COMMON
> >  config RCU_NEED_SEGCBLIST
> >       def_bool ( TREE_RCU || TREE_SRCU || TASKS_RCU_GENERIC )
> >
> > +# The deferral (and the IRQ_WORK it uses) is only needed where call_rcu() /
> > +# call_srcu() can be invoked while a callback-list operation is in flight.
> > +config RCU_DEFER
> > +     def_bool HAVE_NMI || KPROBES || FUNCTION_TRACER || TRACEPOINTS
> > +     select IRQ_WORK
>
> nit: I don't think this config belongs to RCU.
> Do we really need this when majority of kernels enable those?

Paul was worried about some embedded systems paying a performance
penalty as they might not enable these but would still use RCU.

>
> >  config RCU_FANOUT
> >       int "Tree-based hierarchical RCU fanout value"
> >       range 2 64 if 64BIT
> > @@ -3206,6 +3204,103 @@ __call_rcu_common(struct rcu_head *head, 
> > rcu_callback_t func, bool lazy_in)
> >       local_irq_restore(flags);
> >  }
> >
> > +/*
> > + * Stage @head for this CPU's irq_work to re-issue once interrupts are on. 
> >  Only
> > + * the drain side takes a lock, so this stays safe from NMI.
> > + */
> > +static void call_rcu_defer(struct rcu_head *head, rcu_callback_t func)
> > +{
> > +     struct rcu_data *rdp = this_cpu_ptr(&rcu_data);
> > +
> > +     /*
> > +      * Instrumentation on the enqueue path can re-enter here from inside 
> > the
> > +      * drain.  Re-queuing would livelock it, so drop the callback; an NMI
> > +      * cannot loop, so let it through.
> > +
> > +      */
> > +     if (READ_ONCE(rdp->defer_draining) && !in_nmi()) {
> > +             WARN_ONCE(IS_ENABLED(CONFIG_PROVE_RCU),
> > +                       "call_rcu() re-entered during callback drain; 
> > leaking callback\n");
> > +             return;
> > +     }
> > +     head->func = func;
> > +     if (llist_add((struct llist_node *)head, &rdp->defer_head))
> > +             irq_work_queue(&rdp->defer_work);
>
> Should RCU wait for the IRQ work to be processed during e.g.)
> rcu_barrier()?

Yes it should and it does, rcu_barrier() now enqueues these deferred
callbacks from this list before doing the other barrier logic.

Thanks

Reply via email to