On Fri, Dec 04, 2020 at 06:01:56PM +0100, Thomas Gleixner wrote: > From: Thomas Gleixner <t...@linutronix.de> > > On RT a task which has soft interrupts disabled can block on a lock and > schedule out to idle while soft interrupts are pending. This triggers the > warning in the NOHZ idle code which complains about going idle with pending > soft interrupts. But as the task is blocked soft interrupt processing is > temporarily blocked as well which means that such a warning is a false > positive. > > To prevent that check the per CPU state which indicates that a scheduled > out task has soft interrupts disabled. > > Signed-off-by: Thomas Gleixner <t...@linutronix.de> > --- > include/linux/bottom_half.h | 6 ++++++ > kernel/softirq.c | 15 +++++++++++++++ > kernel/time/tick-sched.c | 2 +- > 3 files changed, 22 insertions(+), 1 deletion(-) > > --- a/include/linux/bottom_half.h > +++ b/include/linux/bottom_half.h > @@ -32,4 +32,10 @@ static inline void local_bh_enable(void) > __local_bh_enable_ip(_THIS_IP_, SOFTIRQ_DISABLE_OFFSET); > } > > +#ifdef CONFIG_PREEMPT_RT > +extern bool local_bh_blocked(void); > +#else > +static inline bool local_bh_blocked(void) { return false; } > +#endif > + > #endif /* _LINUX_BH_H */ > --- a/kernel/softirq.c > +++ b/kernel/softirq.c > @@ -138,6 +138,21 @@ static DEFINE_PER_CPU(struct softirq_ctr > .lock = INIT_LOCAL_LOCK(softirq_ctrl.lock), > }; > > +/** > + * local_bh_blocked() - Check for idle whether BH processing is blocked > + * > + * Returns false if the per CPU softirq::cnt is 0 otherwise true. > + * > + * This is invoked from the idle task to guard against false positive > + * softirq pending warnings, which would happen when the task which holds > + * softirq_ctrl::lock was the only running task on the CPU and blocks on > + * some other lock. > + */ > +bool local_bh_blocked(void) > +{ > + return this_cpu_read(softirq_ctrl.cnt) != 0;
__this_cpu_read() Reviewed-by: Frederic Weisbecker <frede...@kernel.org>