On Sun, Mar 10, 2024 at 06:03:30AM -0400, Joel Fernandes wrote: > Hello Ankur and Paul, > > On Mon, Feb 12, 2024 at 09:55:39PM -0800, Ankur Arora wrote: > > With PREEMPT_RCU=n, cond_resched() provides urgently needed quiescent > > states for read-side critical sections via rcu_all_qs(). > > One reason why this was necessary: lacking preempt-count, the tick > > handler has no way of knowing whether it is executing in a read-side > > critical section or not. > > > > With PREEMPT_AUTO=y, there can be configurations with (PREEMPT_COUNT=y, > > PREEMPT_RCU=n). This means that cond_resched() is a stub which does > > not provide for quiescent states via rcu_all_qs(). > > > > So, use the availability of preempt_count() to report quiescent states > > in rcu_flavor_sched_clock_irq(). > > > > Suggested-by: Paul E. McKenney <paulmck@xxxxxxxxxx> > > Signed-off-by: Ankur Arora <ankur.a.arora@xxxxxxxxxx> > > --- > > kernel/rcu/tree_plugin.h | 11 +++++++---- > > 1 file changed, 7 insertions(+), 4 deletions(-) > > > > diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h > > index 26c79246873a..9b72e9d2b6fe 100644 > > --- a/kernel/rcu/tree_plugin.h > > +++ b/kernel/rcu/tree_plugin.h > > @@ -963,13 +963,16 @@ static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp) > > */ > > static void rcu_flavor_sched_clock_irq(int user) > > { > > - if (user || rcu_is_cpu_rrupt_from_idle()) { > > + if (user || rcu_is_cpu_rrupt_from_idle() || > > + (IS_ENABLED(CONFIG_PREEMPT_COUNT) && > > + !(preempt_count() & (PREEMPT_MASK | SOFTIRQ_MASK)))) { > > I was wondering if it makes sense to even support !PREEMPT_RCU under > CONFIG_PREEMPT_AUTO. > > AFAIU, this CONFIG_PREEMPT_AUTO series preempts the kernel on > the next tick boundary in the worst case, with all preempt modes including > the preempt=none mode. > > Considering this, does it makes sense for RCU to be non-preemptible in > CONFIG_PREEMPT_AUTO=y? Because if that were the case, and a read-side critical > section extended beyond the tick, then it prevents the PREEMPT_AUTO preemption > from happening, because rcu_read_lock() would preempt_disable(). Yes, it does make sense for RCU to be non-preemptible in kernels built with CONFIG_PREEMPT_AUTO=y and either CONFIG_PREEMPT_NONE=y or CONFIG_PREEMPT_VOLUNTARY=y. As noted in earlier discussions, there are systems that are adequately but not abundantly endowed with memory. Such systems need non-preemptible RCU to avoid preempted-reader OOMs. Note well that non-preemptible RCU explicitly disables preemption across all RCU readers. Thanx, Paul > To that end, I wonder if CONFIG_PREEMPT_AUTO should select CONFIG_PREEMPTION > (or CONFIG_PREEMPT_BUILD, not sure which) as well because it does cause > kernel preemption. That then forces selection of CONFIG_PREEMPT_RCU as well. > > thanks, > > - Joel > > > > > > > > > > > /* > > * Get here if this CPU took its interrupt from user > > - * mode or from the idle loop, and if this is not a > > - * nested interrupt. In this case, the CPU is in > > - * a quiescent state, so note it. > > + * mode, from the idle loop without this being a nested > > + * interrupt, or while not holding a preempt count. > > + * In this case, the CPU is in a quiescent state, so note > > + * it. > > * > > * No memory barrier is required here because rcu_qs() > > * references only CPU-local variables that other CPUs > > -- > > 2.31.1 > >