本文系轉(zhuǎn)載,著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。
來源: 微信公眾號linux閱碼場(id: linuxdev)
問答
問:Linux的中斷可以嵌套嗎?
答:以前是可以嵌套的,現(xiàn)在不可以!
歷史
早前的Linux內(nèi)核版本,中斷分為兩種:
快中斷,申請的時候帶IRQF_DISABLED標(biāo)記,在IRQ HANDLER里面不允許新的中斷進(jìn)來;
慢中斷,申請的時候不帶IRQF_DISABLED標(biāo)記,在IRQ HANDLER里面允許新的其他中斷嵌套進(jìn)來。
老的Linux內(nèi)核中,如果一個中斷服務(wù)程序不想被別的中斷打斷,我們能看到這樣的代碼:
request_irq(FLOPPY_IRQ, floppy_interrupt,\
- IRQF_DISABLED, "floppy", NULL)
現(xiàn)在
在2010年如下的commit中,IRQF_DISABLED被作廢了:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e58aa3d2d0cc

它的commit log清晰地解釋中斷嵌套可能引入的一些risk,比如stack溢出等。也就是說,從這個commit開始,實際Linux已經(jīng)不再支持中斷的嵌套, 也沒有快慢中斷的概念了,IRQF_DISABLED標(biāo)記也作廢了。在IRQ HANDLER里面,無論一個中斷設(shè)置還是不設(shè)置IRQF_DISABLED, 內(nèi)核都不會開啟CPU對中斷的響應(yīng):

這個作廢的IRQF_DISABLED標(biāo)記,在內(nèi)核已經(jīng)沒有任何的意義了。后來,這個標(biāo)記本身,在內(nèi)核里面也被刪除了,徹底成為過往:

硬件
中斷發(fā)生后,一般硬件會自動屏蔽CPU對中斷的響應(yīng),而軟件層面上,直到IRQ HANDLER做完,才會重新開啟中斷。比如,對于ARM處理器而言,exception進(jìn)來的時候,硬件都會自動屏蔽中斷:

也就是說,當(dāng)ARM處理器收到中斷的時候,它進(jìn)入中斷模式,同時ARM處理器的CPSR寄存器的IRQ位會被硬件設(shè)置為屏蔽IRQ。
Linux內(nèi)核會在如下2個時候重新開啟CPSR對IRQ的響應(yīng):
- 從IRQ HANDLER返回中斷底半部的SOFTIRQ
- 從IRQ HANDLER返回一個線程上下文
從1大家可以看出,SOFTIRQ里面是可以響應(yīng)中斷的。
更多精彩更新中……歡迎關(guān)注微信公眾號:linux閱碼場(id: linuxdev)