Article Directory
1. Interrupt and shield thoughts
Interrupt masking, as its name suggests, shields the CPU
interrupt response function to solve the race condition problem caused by concurrency.
What are the advantages and disadvantages of shielding interrupts before entering the critical section?
The benefits are :
- Guaranteed not to be interrupted by interrupts when executing critical section code
- At the same time, the process scheduling of the system is closely related to interrupts, which also limits the concurrency of system processes and solves the race condition problem caused by system process concurrency.
The disadvantages are :
Linux
In the kernel, in addition to system process scheduling relying on interrupts, there are also many asynchronousI/O
operations that rely on interrupts. Therefore, shielding interrupts for a long time is very dangerous and will seriously affect the system. Therefore, the critical section code is also required to be short.- Turning off interrupts can solve process scheduling and race conditions caused by interrupts, but these are all internal
CPU
, and forSMP
symmetric multiprocessors, it is still inevitable to receive otherCPU
interrupts. Therefore, it does not solve the race condition caused bySMP
multipleCPU
Therefore, interrupt masking alone is usually not a recommended way to avoid race conditions
2. Implementation of Linux kernel interrupt shielding
2.1 API interface provided by the Linux kernel
Regarding interrupt masking,
Linux
the interfaces provided by the kernel are as follows:
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底半部中断
2.2 API interface implementation analysis
Because interrupt masking is related to the underlying chip architecture, different architectures have different processing methods, let's take it as
ARM
an example
2.2.1 local_irq_enable
#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_enable
static inline void arch_local_irq_enable(void)
{
asm volatile(
" cpsie i @ arch_local_irq_enable"
:
:
: "memory", "cc");
}
Function introduction : local_irq_enable
The function is used to set CPSR
the interrupt enable bit in the register to 1, so that CPU
the interrupt can be responded.
Related implementations :
asm
: declares an inline assembly expression
cpsie i
: Assembly instruction, set the bit CPSR
of the register I
to allow this CPU
response interrupt.
memory
: Explain to the assembly that the memory has changed here, similar to the role of a memory barrier
cc
: flag indicating that the condition code may be modified
Assembly code syntax: https://www.jianshu.com/p/57fef17149ae
2.2.2 arch_local_irq_disable
#define arch_local_irq_disable arch_local_irq_disable
static inline void arch_local_irq_disable(void)
{
asm volatile(
" cpsid i @ arch_local_irq_disable"
:
:
: "memory", "cc");
}
Function introduction : arch_local_irq_disable
The function is used to set CPSR
the interrupt enable bit in the register to 0, thereby prohibiting CPU
the response to interrupt.
Related implementation : ditto
cpsid
: It is an assembly instruction, which is used to clearCPSR
the interrupt flag of the register to disable the interrupt!
2.2.3 arch_local_irq_save
#define arch_local_irq_save arch_local_irq_save
static 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;
}
Function introduction : arch_local_irq_save
Function, used to save the current interrupt status and disable interrupts.
Related implementations :
mrs %0 IRQMASK_REG_NAME_R
: mrs
The instruction moves the value of the register IRQMASK_REG_NAME_R
specified by the macro into a variable.IRQMASK
flags
Detailed Explanation of MRS Commands
2.2.4 arch_local_irq_restore
/*
* restore saved IRQ & FIQ state
*/
#define arch_local_irq_restore arch_local_irq_restore
static inline void arch_local_irq_restore(unsigned long flags)
{
asm volatile(
" msr " IRQMASK_REG_NAME_W ", %0 @ local_irq_restore"
:
: "r" (flags)
: "memory", "cc");
}
Function introduction : arch_local_irq_restore
function, used to restore the current interrupt status and open the interrupt.
Related implementation : ditto
Regarding
local_bh_disable
thelocal_bh_enable
two interfaces, it involves the bottom half of the interrupt mechanism, the content is more complicated, and it will be disassembled separately later!
3. Summary
This article mainly understands the following points:
- Interrupt Shielding Thoughts
- Advantages and Disadvantages of Interrupt Masking
Linux
The interrupt mask interface provided by the kernel- Basic assembly implementation of interrupt mask
Like + follow, never get lost