use*_*111 2 linux-kernel interrupt-handling
我有一个具有以下配置的系统;
当 SOFTIRQ 1 运行时,中断 B 出现,然后 ISR B 启动。当 ISR B 发生 irq_exit() 时,它将调用 softirq。因此,它将调度 SOFTIRQ 2(不处理被中断的 SOFTIRQ 1)。
是正确的说法吗?
另一个问题。此时,如果 SOFTIRQ 1 禁用“bottom_half”,我们检测到下半部分被禁用并跳过 SOFTIRQ 2 的执行?提前致谢!
也许您对 SOFTIRQ 和 HARDIRQ 感到困惑。软中断在Linux内核中的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();
}
Run Code Online (Sandbox Code Playgroud)
正如评论所说,如果您在 softirq A 中并且 IRQ B 进入,则 IRQ B 处理将结束 - 在完成当前 SOFTIRQ A 后重新运行。
为了强调所有硬件都不会调用“raise_softirq()”,搜索linux内核会产生以下结果(没有来自硬件,来自“驱动程序”分支):
在网络 IRQ 处理程序中 - napi_schedule() 被调用。(通常在所有驱动程序 IRQ 处理程序中搜索“sched”)。以下来自drivers/net/usb/r8152.c: