- 论坛徽章:
- 7
|
本帖最后由 smalloc 于 2010-09-08 00:24 编辑
塑料袋兄讲的不错.
ksoftirqd嵌套ksoftirqd自然不可能.每处理器只有一个ksoftirqd.
不过ULK3上是说有5处,而不是2处.
两一个重要的地方是local_bh_enable中也调用do_softirq.
另外程序保证是各级上的软中断处理函数不相互打断,而不是do_softirq之间不相互打断.
从代码细节上讲,do_softirq内部是有一部分互斥的,就是利用那个preempt_count中的字段.
从do_softirq到__do_softirq串起来看大致为: (忽略不相干代码)
1, in_interrupt()判断是否退出
2, 关本地中断
3, 禁止本地bh
4, 开中断
5, 调用处理函数
...
...
从中可以看出,判断和禁止(既 1 和 3 )并不是原子的.
那么可以设想,在进程上下文调用local_bh_enable时或者ksoftirqd中, 进入do_softirq. 当执行到1以后,仍然可以被另一个中断结束时的do_softirq嵌套.
local_bh_enable中有个配置 CONFIG_TRACE_IRQFLAGS
可以阻止这个情况的发生.
还好的是从第2步开始后就不能在发生这种嵌套了.于是处理函数全部都被保护起来.
这段代码看起来像是一个锁. 先测试, 然后上锁.
在单处理器的环境中.即使2步不是原子的,也是安全的,但是在可抢占的环境下不起作用.
在多处理器环境中的同步需要的是自旋锁, 对一个处理器而言_bh仅仅防止嵌套. |
|