您可能混淆了 SOFTIRQ 和 HARDIRQ。 Linux 内核中的 Softirq 是 IRQ 处理中的“bottom_half”,由任务调度器调度执行以处理延迟的 IRQ 处理。在此处理期间,它可能会处理多个延迟 IRQ 处理,例如您的 IRQ A 和 IRQ B。
但是如果有任何IRQ进入系统,它会触发ISR处理程序,并且不会立即触发任何SOFTIRQ,只是被安排在以后处理,而不是“调用”作为你的措辞说。 (即,所有硬件 IRQ 处理程序都不应该调用 raise_softirq(),而是安排一个处理程序进行 IRQ 处理)
总而言之,对于您的场景:
在 ISR B 结束后,它可能会提交 SOFTIRQ B 以供以后处理 - 但它不会调用 raise_softirq()。但由于 SOFTIRQ A 中途被拦截,任何硬件中断后,它都会继续之前的最后一个任务,所以 SOFTIRQ A 会执行到完成。
详细说明raise_softirq()内部,调用raise_softirq_irqoff():
inline void raise_softirq_irqoff(unsigned int nr)
{
__raise_softirq_irqoff(nr);
/*
* If we're in an interrupt or softirq, we're done
* (this also catches softirq-disabled code). We will
* actually run the softirq once we return from
* the irq or softirq.
*
* Otherwise we wake up ksoftirqd to make sure we
* schedule the softirq soon.
*/
if (!in_interrupt())
wakeup_softirqd();
}
正如评论所说,如果您在 softirq A 中并且 IRQ B 进入,IRQ B 处理将结束 - 在完成当前 SOFTIRQ A 后重新运行。
为了强调并非所有硬件都调用“raise_softirq()”,搜索linux内核得到以下结果(没有来自硬件,它来自“驱动程序”分支):
在网络 IRQ 处理程序中 - napi_schedule() 被调用。 (一般在所有驱动程序 IRQ 处理程序中搜索“sched”)。以下来自drivers/net/usb/r8152.c: