On Fri, Jun 12, 2020 at 6:55 AM Thomas Gleixner <tglx@xxxxxxxxxxxxx> wrote: > > The idea of conditionally calling into rcu_irq_enter() only when RCU is > not watching turned out to be not completely thought through. > > Paul noticed occasional premature end of grace periods in RCU torture > testing. Bisection led to the commit which made the invocation of > rcu_irq_enter() conditional on !rcu_is_watching(). > > It turned out that this conditional breaks RCU assumptions about the idle > task when the scheduler tick happens to be a nested interrupt. Nested > interrupts can happen when the first interrupt invokes softirq processing > on return which enables interrupts. If that nested tick interrupt does not > invoke rcu_irq_enter() then the nest accounting in RCU claims that this is > the first interrupt which might mark a quiescient state and end grace > periods prematurely. > > Change the condition from !rcu_is_watching() to is_idle_task(current) which > enforces that interrupts in the idle task unconditionally invoke > rcu_irq_enter() independent of the RCU state. > > This is also correct vs. user mode entries in NOHZ full scenarios because > user mode entries bring RCU out of EQS and force the RCU irq nesting state > accounting to nested. As only the first interrupt can enter from user mode > a nested tick interrupt will enter from kernel mode and as the nesting > state accounting is forced to nesting it will not do anything stupid even > if rcu_irq_enter() has not been invoked. Acked-by: Andy Lutomirski <luto@xxxxxxxxxx>