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(). 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 >