Re: [PATCH 4/7] rcu: handle quiescent states for PREEMPT_RCU=n, PREEMPT_COUNT=y

From: Ankur Arora
Date: Thu Oct 10 2024 - 14:01:06 EST



Paul E. McKenney <paulmck@xxxxxxxxxx> writes:

> On Wed, Oct 09, 2024 at 12:05:47PM -0700, Ankur Arora wrote:
>>
>>
>> Ankur Arora <ankur.a.arora@xxxxxxxxxx> writes:
>>
>> > 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 needed, was 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_LAZY=y, there can be configurations with PREEMPT_COUNT=y,
>> > PREEMPT_RCU=n, where cond_resched() is a stub that does not provide
>> > quiescent states via rcu_all_qs().
>> >
>> > So, use the availability of preempt_count() to report quiescent states
>> > in rcu_flavor_sched_clock_irq().
>>
>> A note about the inverse of this case, where we might have long running
>> loops which only temporarily enable preemption and thus would be
>> unlikely to align themselves with the tick: in prior discussions [1]
>> Paul had pointed the need for providing for forcing a context switch
>> in such a scenario.
>>
>> I had a patch which did that, but I think it is unnecessary since this
>> clause in rcu_sched_clock_irq() should already handle it.
>>
>> void rcu_sched_clock_irq(int user) {
>> ...
>> /* The load-acquire pairs with the store-release setting to true. */
>> if (smp_load_acquire(this_cpu_ptr(&rcu_data.rcu_urgent_qs))) {
>> /* Idle and userspace execution already are quiescent states. */
>> if (!rcu_is_cpu_rrupt_from_idle() && !user) {
>> set_tsk_need_resched(current);
>> set_preempt_need_resched();
>> }
>> __this_cpu_write(rcu_data.rcu_urgent_qs, false);
>> }
>>
>> Paul?
>
> As long as the tick is actually enabled.
>
> But looking deeper, there is code in force_qs_rnp() and
> rcu_watching_snap_recheck() to force the tick on CPUs that don't
> response to the grace period soon enough via the -1 return from the
> rcu_watching_snap_recheck() function and via resched_cpu().

Ah. I had missed that path. Thanks.

--
ankur