On Tue, Jul 28, 2026 at 09:21:55AM -0700, Paul E. McKenney wrote:
> On Tue, Jul 28, 2026 at 10:57:57AM +0530, Shrikanth Hegde wrote:
> > Hi Paul, Christophe,
> > 
> > On 7/27/26 11:59 PM, Christophe Leroy (CS GROUP) wrote:
> > > Hi Shrikanth,
> > > 
> > 
> > > 
> > > That's right with CONFIG_PREEMPT_DYNAMIC=y
> > > 
> > > With CONFIG_PREEMT_DYNAMIC=n:
> > > - CONFIG_PREEMPT (full) implies CONFIG_PREEMPT_RCU
> > > - CONFIG_PREEMPT_LAZY (lazy) doesn't imply CONFIG_PREEMPT_RCU
> > > 
> > > because of kernel/rcu/Kconfig,
> > > 
> > > config PREEMPT_RCU
> > >      bool
> > >      default y if (PREEMPT || PREEMPT_RT || PREEMPT_DYNAMIC)
> > >      select TREE_RCU
> > > 
> > > Christophe
> > > 
> > > 
> > 
> > Right.
> > 
> > Looks like __rcu_read_unlock can set need_resched bit if it find irq were 
> > disabled
> > and rcu_read_unlock_special.s is set. I don't have much clue about it.
> > So, after seeing __rcu_read_unlock for PREEMPT_RCU I have these concerns 
> > now.
> 
> This is because irq-disabled regions of code act as RCU readers.
> For non-preemptible RCU (even in CONFIG_PREEMPT_LAZY=y kernels), this
> comes for free.  In contrast, preemptible RCU must explicitly (and,
> as you noticed, rather painfully) handle the irq-disabled case:
> 
>       rcu_read_lock();
>       do_something();
>       local_irq_disable();
>       do_something_else();
>       rcu_read_unlock();
>       do_yet_another_thing();
>       local_irq_enable();
> 
> Here, the RCU reader extends all the way from the rcu_read_lock() to
> the final local_irq_enable().  And this is why RCU checks for IRQs being
> disabled in __rcu_read_unlock().
> 
> > In current upstream, lazy is a preemption mode with preempt_enable being a 
> > preemptible point,
> > 
> > 1. If PREEMPT_LAZY=y and PREEMPT_DYNAMIC=n, then PREEMPT_RCU=n. That seems 
> > wrong. It is supposed to
> >    do the preemption checks, since preempt_count is actual count with lazy 
> > preemption.
> 
> Sorry, but no, not wrong at all.  This is the way that it is supposed
> to be.  In this configuration, RCU readers explicitly disable preemption.
> This gets us minimal RCU overhead on architectures such as x86 and arm64
> that have prohibited CONFIG_PREEMPT_NONE and CONFIG_PREEMPT_VOLUNTARY.
> Not zero overhead, but minimal overhead given the constraints imposed by
> CONFIG_PREEMPT_LAZY.  This also prevents preemption of RCU readers, which
> is extremely important on datacenter servers that have good and sufficient
> quantities of memory, but which are not well-endowed with memory.

Now, if you would like to be able to manually choose between non-preemptible
and preemptible RCU when when PREEMPT_LAZY=y, *that* we could discuss.

But it looks like you are looking for low overhead, and thus wanting to
avoid preemptible RCU.

                                                        Thanx, Paul

> > 2. PREEMPT_LAZY=y and PREEMPT_DYNAMIC=n and PREEMPT_LAZY=y and 
> > PREEMPT_DYNAMIC=y are supposed
> >    to be similar w.r.t to performance.
> 
> RCU never made that promise.  ;-)
> 
> With PREMPT_DYNAMIC=y, RCU has no choice but to be preemptible, at
> least unless and until someone decides to make RCU's preemptibility be
> changeable at runtime (which I do not recommend).  And we really do need
> non-preemptible RCU for server workloads.
> 
> So it is not just that RCU never made that promise, it is that RCU cannot
> reasonably make that promise.
> 
> >                                        Promise of PREEMPT_DYNAMIC was the 
> > ability to
> >    switch at runtime based on the user workload and his/her preference.
> >    But with  PREEMPT_LAZY=y and PREEMPT_DYNAMIC=y, there is additional cost 
> > due to PREEMPT_RCU.
> >    lazy being the middle ground w.r.t for decent performance, either 
> > PREEMPT_RCU should either kick in
> >    for both cases or bail out for both.
> 
> Absolutely not!!!  Please see above.
> 
> > Before 7.0
> > 3. the same concerns would be true to PREEMPT_VOLUNTARY and PREEMPT_NONE 
> > with PREEMPT_DYNAMIC=y.
> >    Those model never wanted a preemption, but PREEMPT_RCU could have forced 
> > a need_resched to be
> >    set. Which is also likely wrong. No?
> 
> You lost me on this one.  Please give me an explicit sequence of events
> that would cause things to go wrong in this case.
> 
>                                                       Thanx, Paul

Reply via email to