- 论坛徽章:
- 0
|
本帖最后由 honkiko 于 2012-05-22 12:25 编辑
回复 1# asuka2001
对于irqs_disabled()的检查,我的理解,在irqs_disabled()的状态下,调用可能打开中断的函数/宏,都是有风险的。而local_bh_enable()就是这样的函数/宏。
在 (!in_irq && irqs_disabled()) 状态,而如果这个local_bh_enable()减掉的是最后一个SOFTIRQ_DISABLE_OFFSET, 就会进入do_softirq() -> __do_softirq(), 里面会无条件打开中断,然后执行所有pending的软中断处理函数。
下面的代码在这样的情况下会跟预期的情况不一样:
/**软中断或进程上下文中*/
local_irq_disable();
...操作链表A \
local_bh_enable(); 临界区
...继续操作链表A /
local_irq_enable();
假设某个中断也会操作链表A, 本来这个进程预期通过关中断,确保这个临界区不可能被中断所打断,来保护链表A。
但是,local_bh_enable()可能会打开中断。 这期间那个中断如果发生,也会去操作链表A, 而且是前面的进程也正处在临界区的时候。
在中断上下文,为什么不让调local_bh_enable()?想了一下,好像也有类似的原因:
/**进程上下文中*/
local_bh_disable()
...临界区X
local_bh_enable()
本来进程中认为在临界区X中的代码,是不会被软中断所打断的。 或者说进程在执行临界区X的代码时,不用担心有软中断会进入临界区。
但是,如果在某个中断里面,调用了local_bh_enable(), 那所有进程上下文的类似的临界区,都得不到这样的保证了。
因为在这段临界区,是可能发生中断的,然后如果local_bh_enable,正好减掉了最后一个SOFTIRQ_DISABLE_OFFSET, 在中断返回时,就会调用do_softirq了。
|
|