On 2021-08-18 15:46:51 [-0700], Paul E. McKenney wrote: … > > + /* > > + * Ideally these sequences would be detected in debug builds > > + * (regardless of RT), but until then don't stop testing > > + * them on non-RT. > > + */ > > + if (IS_ENABLED(CONFIG_PREEMPT_RT)) { > > + /* > > + * Can't disable bh in atomic context if bh was already > > + * disabled by another task on the same CPU. Instead of > > + * attempting to track this, just avoid disabling bh in atomic > > + * context. > > + */ > > + mask &= ~atomic_bhs; > > At some point, we will need to test disabling bh in atomic context, > correct? Or am I missing something here? Ideally there is no disabling bh in atomic context (on RT). Having it breaks some fundamental rules how softirq handling and the bh related synchronisation is implemented. Given that the softirq handler is invoked in thread context and preemption is not disabled as part of spin_lock(), rcu_read_lock(), and interrupts are in general not disabled in the interrupt handler or spin_lock_irq() there is close to zero chance of disabling bh in atomic context on RT. In reality there is (of course) something that needs to disable bh in atomic context and it happens only during boot up (or from idle unless I'm mistaken). It is required that bh disable and its enable part (later) happens in the same context that is if bh has been disabled in preemptible context it must not be enabled in atomic context (and vice versa). The bottom line is that there must not be a local_bh_disable() in atomic context if another (preempted) task already did a local_bh_disable() on the same CPU, like in the following scenario on one CPU: TASK A TASK B local_bh_disable(); … preempted preempt_disable(); local_bh_disable(); Then this breaks the synchronisation that is otherwise provided by local_bh_disable(). Without that preempt_disable() TASK B would block (and wait) until TASK A completes its BH section. In atomic context it is not possible and therefore not allowed. Sebastian