5

local_bh_disable禁用下半部分(softirqs)的处理。Softirq 在中断返回路径或 ksoftirqd-(per cpu)-thread 上进行处理,如果系统遭受严重的 softirq-load,该线程将被唤醒。

preempt_disable禁用抢占,这意味着当线程在preempt_disable<->preemt_enable范围内执行时,调度程序不会将其置于睡眠状态。这意味着,如果当前线程在该范围内时发生系统定时器中断,它可能会更新调度程序的计费表,但不会将上下文切换到另一个线程。这包括softirqd。

local_irq_disablelocal_irq_save禁用本地 cpu 的中断。这意味着本地 cpu 不会对任何 irq 做出反应,因此它不会运行任何中断返回路径,因此无法在那里运行 softirq。

假设我的上述陈述是正确的(我不确定),那么在local_bh_disable你调用之后调用preempt_disable并且local_irq_save(在进程上下文中)调用不是多余的吗?

4

2 回答 2

4

是的。一旦调用了 local_irq_save / disable,就不需要进一步的保护——你不会被打断(除了 NMI 或代码中的异常)。

但是,您通常会发现一些代码被设计为可从不同的上下文调用,因此它们可能会为某些最终在某些路径中冗余的子操作提供保护。

于 2014-06-17T21:02:49.893 回答
0

preempt_disable/enable 范围确保在该范围内调用 schedule 什么都不做(即禁用抢占)。但是,softirq 或 irq 可以打断你。

禁用 irq 只会禁用硬中断,因为禁用 bh(softirqs) 只会禁用软件中断,但您需要明确指定要禁用的中断。有4个级别:NMI、IRQ、softirq、进程。NMI(non maskable interrupts)可以中断IRQ、softirq、进程;IRQ可以中断一个softirq和一个进程;softirqs 可以中断一个进程。

在 local_irq_save() 之后调用 local_bh_disable() 可能是多余的(不确定),但是如果你想禁用 BH,肯定需要在 preempt_disable() 之后调用 local_bh_disable()。

于 2020-05-21T14:09:30.850 回答