Re: [PATCH v2] softirq: Preserve interrupt context during IRQ exit
From: Karl Mehltretter
Date: Tue Sep 22 2026 - 20:19:30 EST
On Mon, Sep 21, 2026 at 03:50:15PM +0100, Sebastian Andrzej Siewior wrote:
> The "important" part is this fixing something that is broken today or is
> it just avoiding fallout. We don't have any memory allocations/ locking
> in the mentioned window as far as I know. That would fix things, just
> avoid fallout.
Instrumentation sees the wrong context today, the rest is avoiding
fallout.
There is some locking in the window though. With threaded interrupts,
and always on RT, the window wakes ksoftirqd and ktimers. The tracepoints
of those wakeups then run as if they were in the interrupted task. On RT
can_spin_trylock() does not refuse in there.
> > -Woverflow is on by default. I'll swap the operands:
>
> Is this some gcc-17 thing? I don't remember that I saw it and I did test
> that.
gcc 15.2. Without the casts x86_64_defconfig fails here, because it sets
CONFIG_WERROR:
include/linux/preempt.h:78:25: error: overflow in conversion from
'long unsigned int' to 'int' changes value from '18446744073692774656'
to '-16776960' [-Werror=overflow]
clang 21 warns as well (-Wconstant-conversion). With the operands
swapped the value is positive and fits an int, so no cast is needed.
> > HARDIRQ_OFFSET after the addition. In softirq_handle_begin() I will move
> > lockdep_softirqs_off() before the assertion. Then the lockdep softirq
> > state is consistent if the assertion fires and printk runs.
>
> Right. I mean you have one state and this what you want test for. I
> don't think it make sense to test before and after arithmetics.
> I am just not sure if those warnings should be hidden behind
> CONFIG_DEBUG_PREEMPT similar as preempt_count_add() does it. Maybe it is
> not hot-enough-path to worry about it.
I'll keep them for now. They only run when softirqs are handled on irq
exit, so much less often than preempt_count_add(), and the softirq
handlers run right after them. With both checks softirq.o has 8 more
instructions on x86-64 and 11 on arm64 on that path.
> > Yes, that is the intent. irq_count() would skip the wakeup when the
> > interrupt hit a BH disabled or softirq serving section. The old test
> > did not skip it, and nothing else handles pending_timer_softirq.
>
> I am slightly unsure but I think we want the wakeup of the timer thread
> even if we are in a bh-disabled section. If the current task is a
> SCHED_OTHER then the wake-up preempt it. If the thread is already woken
> then the wake-up will do nothing.
Yes. I'll use !in_nmi() && hardirq_count() == HARDIRQ_OFFSET, without
softirq_count().
> > Today the wakeup already runs before the rearm when no softirq is
> > pending. Does the old order have a reason that I do not see? Then I
> > keep it and document that the timer thread handles such a softirq.
>
> This only matters for the threadirq case. Here invoke_softirq() will
> only wake ksoftirqd and wake_timersd() will only wake the ktimers
> thread. There will be no new softirqs added to the mask. This currently
> is an ugly catch-all for both sides. Ideally only the softirqs raised by
> task X should be handled by task X but the first one will do everything.
OK, I'll drop that change.
Thanks,
Karl