請問local_bh_disable為甚麼要cli再sti?

歡迎提問 debian desktop 相關問題,何謂 desktop ? 舉凡您日常生活會用到的部份,如上網 ( www 、 bbs ..) 、程式設計、繪圖...等等。 通常以 X Window 環境底下問題為主。

請問local_bh_disable為甚麼要cli再sti?

文章cf » 週三 4月 09, 2008 8:03 pm

我這個地方不太懂耶
static void __local_bh_disable(unsigned long ip)
{
//...
raw_local_irq_save(flags);
add_preempt_count(SOFTIRQ_OFFSET);
//...
raw_local_irq_restore(flags);
}
為甚麼他要這樣做呢
感覺不是因為怕先被preempt?
cf
可愛的小學生
可愛的小學生
 
文章: 2
註冊時間: 週二 12月 26, 2006 4:14 pm

Re: 請問local_bh_disable為甚麼要cli再sti?

文章jserv » 週三 4月 09, 2008 8:46 pm

cf 寫:我這個地方不太懂耶
static void __local_bh_disable(unsigned long ip)
{
//...
raw_local_irq_save(flags);
add_preempt_count(SOFTIRQ_OFFSET);
//...
raw_local_irq_restore(flags);
}
為甚麼他要這樣做呢
感覺不是因為怕先被preempt?


如果閣下先去看 2.6 kernel 的 Big kernel lock 實做原理,再回頭思考這邊 BH 的作法,應該就會恍然大悟。

此外,如果要作 source code listing,最好還是指明路徑。另外,這個問題貼在 "debian desktop",似乎艱澀了些 :-)
jserv
懵懂的國中生
懵懂的國中生
 
文章: 116
註冊時間: 週六 5月 08, 2004 7:36 pm

文章orca » 週三 4月 09, 2008 9:00 pm

就我所知,softirq (say A)在執行的時候interrupt也是打開的,這時候要作add_preempt_count的時候,如果其他interrupt也可以進來的話,那麼其他softirq handler (say B)就可能執行,如果B也要add preempt count的話,那就有執行順序上的問題。(如果A先執行的話,那麼B不應該被執行,因為B應該已經被disable了,B只能mark pending而已)

事實上,同種類的tasklet在kernel裡面順序不能改變,同一種tasklet同一時間只能有一個在執行,softirq沒有這個限制,但是需要lock。(可以參考Love的書或者是ULK)

先做cli把interrupt關掉,就可以避免種情況,等到preempt count改變之後(改變preempt_count可以對ISR、softirq、kernel preemption造成影響(可以去看書)。改完preempt_count之後在把執行sti把interrupt打開。

--

參考參考,有錯請指正 :-)
orca
可愛的小學生
可愛的小學生
 
文章: 20
註冊時間: 週三 12月 07, 2005 10:48 pm

文章cf » 週三 4月 09, 2008 9:40 pm

thank you jserv & orca
這篇問題問錯地方了真不好意思
這一段code是在http://lxr.linux.no/linux/kernel/softirq.c來的
而且也沒貼完全
我猜這就是問題所在, 因為
代碼: 選擇全部
#ifdef CONFIG_TRACE_IRQFLAGS
static void __local_bh_disable(unsigned long ip)
{
        //...
        raw_local_irq_save(flags);
        add_preempt_count(SOFTIRQ_OFFSET);
        if (softirq_count() == SOFTIRQ_OFFSET)
                trace_softirqs_off(ip);
        raw_local_irq_restore(flags);
}
#else /* !CONFIG_TRACE_IRQFLAGS */
static inline void __local_bh_disable(unsigned long ip)
{
        add_preempt_count(SOFTIRQ_OFFSET);
        barrier();
}
#endif /* CONFIG_TRACE_IRQFLAGS */

cli/sti要保護的只是若有開trace
防止到softirq_count()之前都不要被preempt

sorry. 下次code會看清楚一點....-.-
cf
可愛的小學生
可愛的小學生
 
文章: 2
註冊時間: 週二 12月 26, 2006 4:14 pm

文章jserv » 週三 4月 09, 2008 9:45 pm

cf 寫:thank you jserv & orca
這篇問題問錯地方了真不好意思
這一段code是在http://lxr.linux.no/linux/kernel/softirq.c來的
而且也沒貼完全
我猜這就是問題所在, 因為
代碼: 選擇全部
#ifdef CONFIG_TRACE_IRQFLAGS
static void __local_bh_disable(unsigned long ip)
{
        raw_local_irq_save(flags);
        add_preempt_count(SOFTIRQ_OFFSET);
        if (softirq_count() == SOFTIRQ_OFFSET)
                trace_softirqs_off(ip);
        raw_local_irq_restore(flags);
}
#else /* !CONFIG_TRACE_IRQFLAGS */
static inline void __local_bh_disable(unsigned long ip)
{
        add_preempt_count(SOFTIRQ_OFFSET);
        barrier();
}
#endif /* CONFIG_TRACE_IRQFLAGS */

cli/sti要保護的只是若有開trace
防止到softirq_count()之前都不要被preempt


No problem. 有找到答案就好 :)

其實這些重要的設計,在 2.6 kernel 的實做變化很大,特別是未來 PREEMPT_RT 整合到 mainline 時,整個 device driver 的模型也會更動,能留意到這些細節就很重要,因為觀念還是通用的。

不過,還是建議繼續分析其他 kernel lock 與 preemption 的設計,相信你可有更多想法。

Good Luck!
jserv
懵懂的國中生
懵懂的國中生
 
文章: 116
註冊時間: 週六 5月 08, 2004 7:36 pm


回到 debian desktop

誰在線上

正在瀏覽這個版面的使用者:沒有註冊會員 和 1 位訪客

cron