Re: [PATCH] softirq: WARN_ON !preemptible() not check softirq cnt in bh disable on RT
From: Xin Zhao
Date: Wed Mar 11 2026 - 13:03:05 EST
hi, Sebastian
On 2026-03-11 16:09 UTC, Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx> wrote:
> > Indeed, it will trigger this warning; it just reduces the probability of it being
> > reported.
> Yes
As you said, the current implementation is good enough. :)
If you think it’s appropriate to change it to (system_state != SYSTEM_BOOTING), you can make
that change later when you git rid of CONFIG_PREEMPT_RT_NEEDS_BH_LOCK. :)
> Funny story: I did a grep for the pattern you described and this s390
> driver was the only thing that popped up.
I'm actually curious why the users of _local_bh_enable, specifically those using the s390
driver, haven't raised the issue that this interface cannot be used in RT-linux. Could it be
that s390 users have never run on RT-linux?
> > Since you also mentioned that later CONFIG_PREEMPT_RT_NEEDS_BH_LOCK will no longer be
> > enabled, at that point, local_bh_disable almost loses its significance. I think it
> > should either be removed or implemented as a no-op, as it no longer achieves our
> > expected effect, and it would be better to save some instruction execution time.
>
> We can't nop it entirely. local_bh_disable() needs remain a RCU read
> section and it needs to ensure that the context does not wonder off to
> another CPU. Also we need to count the disable/enable because once we go
> back to zero, we need to run callbacks which may have queued up.
I did overlook that local_bh_disable() is also considered an RCU critical section and is
used in conjunction with rcu_read_lock_bh(). Although I saw comments in the code like
"/* Required to meet the RCU bottomhalf requirements. */", I don't fully understand why
local_bh_disable must be treated as an RCU read critical section. Is it simply because the
implementation of rcu_read_lock_bh does not directly call __rcu_read_lock and instead relies
on local_bh_disable to proxy this call? I haven't figured this out, and it seems a bit
strange to me.
> And if we queue the softirq on per-task basis rather then per-CPU then
> we don't have the problem that one task completes softirqs queued by
> another one.
Are you suggesting that the future implementation of soft interrupts might be optimized to
use a per-task approach for queuing and processing soft interrupts? I think this is a very
good attempt, as the current handling of soft interrupts is a bit chaotic. High-priority
tasks often end up passively dealing with many low-priority soft interrupt tasks during
local_bh_disable(), effectively acting as 'ksoftirqd'. This seems unreasonable to me, as
it elevates the priority of low-priority tasks for processing.
If soft interrupt handling could be implemented in a per-task manner, it could even lead to
priority inheritance in the future, and possibly work in conjunction with BH workqueues to
thoroughly resolve the long-standing issues of soft interrupts in RT-linux. In my project,
performance problems are often related to __local_bh_disable_ip and various sporadic
latency spikes caused by migrate_disable(). This is quite frustrating.
Xin Zhao