- 論壇徽章:
- 0
|
本帖最后由 honkiko 于 2012-05-22 12:25 編輯
回復(fù) 1# asuka2001
對于irqs_disabled()的檢查,我的理解,在irqs_disabled()的狀態(tài)下,調(diào)用可能打開中斷的函數(shù)/宏,都是有風(fēng)險的。而local_bh_enable()就是這樣的函數(shù)/宏。
在 (!in_irq && irqs_disabled()) 狀態(tài),而如果這個local_bh_enable()減掉的是最后一個SOFTIRQ_DISABLE_OFFSET, 就會進入do_softirq() -> __do_softirq(), 里面會無條件打開中斷,然后執(zhí)行所有pending的軟中斷處理函數(shù)。
下面的代碼在這樣的情況下會跟預(yù)期的情況不一樣:
/**軟中斷或進程上下文中*/
local_irq_disable();
...操作鏈表A \
local_bh_enable(); 臨界區(qū)
...繼續(xù)操作鏈表A /
local_irq_enable();
假設(shè)某個中斷也會操作鏈表A, 本來這個進程預(yù)期通過關(guān)中斷,確保這個臨界區(qū)不可能被中斷所打斷,來保護鏈表A。
但是,local_bh_enable()可能會打開中斷。 這期間那個中斷如果發(fā)生,也會去操作鏈表A, 而且是前面的進程也正處在臨界區(qū)的時候。
在中斷上下文,為什么不讓調(diào)local_bh_enable()?想了一下,好像也有類似的原因:
/**進程上下文中*/
local_bh_disable()
...臨界區(qū)X
local_bh_enable()
本來進程中認為在臨界區(qū)X中的代碼,是不會被軟中斷所打斷的。 或者說進程在執(zhí)行臨界區(qū)X的代碼時,不用擔(dān)心有軟中斷會進入臨界區(qū)。
但是,如果在某個中斷里面,調(diào)用了local_bh_enable(), 那所有進程上下文的類似的臨界區(qū),都得不到這樣的保證了。
因為在這段臨界區(qū),是可能發(fā)生中斷的,然后如果local_bh_enable,正好減掉了最后一個SOFTIRQ_DISABLE_OFFSET, 在中斷返回時,就會調(diào)用do_softirq了。
|
|