Linux kernel 软irq上下文中的抢占

Linux kernel 软irq上下文中的抢占,linux-kernel,interrupt-handling,Linux Kernel,Interrupt Handling,我有一个具有以下配置的系统 SMP平台(但我只关注本地CPU)和抢占关闭 ISR A->raise_软件问题(1) ISR B->raise_软件问题(2) 当SOFTIRQ 1运行时,中断B出现,然后ISR B启动。 当irq_exit()发生在ISR B时,它将调用softirq。因此,它将调度SOFTIRQ 2(不考虑被中断的SOFTIRQ 1) 这是正确的声明吗 另一个问题。此时,如果SOFTIRQ 1禁用了“下半部分”,那么我们在哪里检测下半部分被禁用并跳过SOFTIRQ 2的执行

我有一个具有以下配置的系统

  • SMP平台(但我只关注本地CPU)和抢占关闭
  • ISR A->raise_软件问题(1)
  • ISR B->raise_软件问题(2)
当SOFTIRQ 1运行时,中断B出现,然后ISR B启动。 当irq_exit()发生在ISR B时,它将调用softirq。因此,它将调度SOFTIRQ 2(不考虑被中断的SOFTIRQ 1)

这是正确的声明吗

另一个问题。此时,如果SOFTIRQ 1禁用了“下半部分”,那么我们在哪里检测下半部分被禁用并跳过SOFTIRQ 2的执行?
提前谢谢

也许你混淆了软irq和硬irq。Linux内核中的Softirq是IRQ处理中的“下半部分”,由任务调度器调度执行,以处理延迟的IRQ处理。在这个处理过程中,它可能会处理多个延迟的IRQ处理,比如在你的例子中的IRQ A和IRQ B

但是,如果任何IRQ进入系统,它将触发ISR处理程序,并且不会立即触发任何SOFTIRQ,只计划在以后处理,而不是按照您的措辞所说的“调用”。(即,所有硬件IRQ处理程序都不应该调用raise_softirq(),而是为IRQ处理安排一个处理程序)

总之,对于您的场景:

ISR B结束后,它可能会提交SOFTIRQ B供以后处理-,但它不会调用raise\u SOFTIRQ()。但是由于SOFTIRQ A被中途拦截,在任何硬件中断之后,它将继续之前的最后任务,因此SOFTIRQ A将执行到完成

要详细说明raise\u softirq()internal,它调用raise\u softirq\u irqoff():

正如评论所说,如果您在softirq A中,并且IRQ B进入,IRQ B处理将结束-在完成当前softirq A后重新运行

为了强调并非所有硬件都调用“raise_softirq()”,对linux内核的搜索会产生以下结果(没有一个结果来自硬件,它来自“驱动程序”分支):

在网络IRQ处理程序中,调用napi_schedule()。(通常在所有驱动程序IRQ处理程序中搜索“sched”)。以下内容来自drivers/net/usb/r8152.c:

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();
}