
中斷屏蔽,正如其名,屏蔽掉CPU
的中斷響應功能,解決并發引起的競態問題。
在進入臨界區前屏蔽中斷,這么做有什么好處,以及有什么弊端?
好處在于:
(資料圖片)
弊端在于:
Linux
內核中,除了系統進程調度依賴中斷,還有一些異步I/O
等眾多操作都依賴中斷,因此長時間屏蔽中斷是很危險的,會對系統造成嚴重影響,因此也要求臨界區代碼要簡短。關閉中斷能夠解決進程調度、中斷引發的競態,但是這些都是單CPU
內部的,對于SMP
對稱多處理器,仍然不可避免的會收到其他CPU
的中斷。因此,并不能解決SMP
多CPU
引發的競態因此,單獨使用中斷屏蔽通常不是一種值得推薦的避免競態的方法
關于中斷屏蔽,
Linux
內核所提供的接口如下:
local_irq_enable() // 使能本CPU的中斷local_irq_disable() // 禁止本CPU的中斷local_irq_save(flags) // 禁止本CPU的中斷,并保存CPU中斷位的信息local_irq_restore(flags) // 使能本CPU的中斷,并恢復CPU中斷位的信息local_bh_disable(void) // 禁止本CPU底半部中斷local_bh_enable(void) // 使能本CPU底半部中斷
因為中斷屏蔽與底層芯片架構有關,不同架構處理方式不同,我們以
ARM
為例
#define local_irq_enable() do { raw_local_irq_enable(); } while (0)#define raw_local_irq_enable() arch_local_irq_enable()#define arch_local_irq_enable arch_local_irq_enablestaticinline void arch_local_irq_enable(void){ asm volatile( " cpsie i @ arch_local_irq_enable" : : : "memory", "cc");}
函數介紹:local_irq_enable
函數用于將CPSR
寄存器中的中斷使能位設為1,從而使得CPU
能夠響應中斷。
相關實現:
asm
:聲明一個內聯匯編表達式
cpsie i
:匯編指令,設置CPSR
寄存器的I
位,來允許本CPU
響應中斷。
memory
:向匯編說明,此處內存發生了更改,類似于內存屏障的作用
cc
:表示可能會修改條件碼的標志
#define arch_local_irq_disable arch_local_irq_disablestatic inline void arch_local_irq_disable(void){ asm volatile( " cpsid i @ arch_local_irq_disable" : : : "memory", "cc");}
函數介紹:arch_local_irq_disable
函數用于將CPSR
寄存器中的中斷使能位設為0,從而禁止CPU
響應中斷。
相關實現:同上
cpsid
:是匯編指令,用于清除CPSR
寄存器的中斷標志,以禁止中斷!#define arch_local_irq_save arch_local_irq_savestatic inline unsigned long arch_local_irq_save(void){ unsigned long flags; asm volatile( " mrs%0, " IRQMASK_REG_NAME_R " @ arch_local_irq_save\\n" " cpsid i" : "=r" (flags) : : "memory", "cc"); return flags;}
函數介紹:arch_local_irq_save
函數,用于保存當前中斷狀態并禁用中斷。
相關實現:
mrs %0 IRQMASK_REG_NAME_R
:mrs
指令將由IRQMASK_REG_NAME_R
宏指定的IRQMASK
寄存器的值移動到flags
變量中。
/* * restore saved IRQ & FIQ state */#define arch_local_irq_restore arch_local_irq_restorestatic inline void arch_local_irq_restore(unsigned long flags){ asm volatile( " msr " IRQMASK_REG_NAME_W ", %0 @ local_irq_restore" : : "r" (flags) : "memory", "cc");}
函數介紹:arch_local_irq_restore
函數,用于恢復當前中斷狀態并打開中斷。
相關實現:同上
關于
local_bh_disable
和local_bh_enable
兩個接口,涉及到中斷底半部機制,內容較為復雜,放在后面單獨拆解!
該篇文章,主要了解以下幾點:
中斷屏蔽的思想中斷屏蔽的好處與不足Linux
內核提供的中斷屏蔽接口中斷屏蔽的基本匯編實現 標簽: