常用中断控制方法解析

中断控制主要包含两部分内容:

  • 禁止和激活中断
  • 查询中断系统的状态

禁止和激活中断

简单的禁止和激活中断

这种方法存在风险,比如,在执行 local_irq_enable() 时,会无条件的激活中断,但是可能在开始时原中断就是关闭的。

local_irq_disable();
/* 中断禁止区 */
local_irq_enable();

对于 x86 体系,这两个函数的具体实现如下,也就是汇编指令的直接使用:

arch/x86/include/asm/irqflags.h

static inline void local_irq_disable(void)
{
	asm volatile("cli": : :"memory");
}

static inline void local_irq_enable(void)
{
	asm volatile("sti": : :"memory");
}

带状态的禁止和激活中断

在关闭中断时,将原中断状态保存在 unsigned long 中,这样在恢复中断时,可以将状态安全地恢复到原来的状态。

unsigned long flags;
local_irq_save(flags);
/* 中断禁止区 */
local_irq_restore(flags);

对于 x86 体系,这两个函数的实现如下,由于函数经多层嵌套,为了表示方便,省略了一些中间嵌套的函数名称。

arch/x86/include/asm/irqflags.h

/* irq_save 包含两步,即保存状态,禁止中断*/
static inline unsigned long local_irq_save(void)
{
	unsigned long flags = native_save_fl();

	local_irq_disable();

	return flags;
}

static inline unsigned long native_save_fl(void)
{
	unsigned long flags;
	
	asm volatile("# __raw_save_flags\n\t"
		     "pushf ; pop %0"
		     : "=rm" (flags)
		     : /* no input */
		     : "memory");

	return flags;
}

/* 恢复中断状态仅仅把状态标志复原就可 */
static inline void local_irq_restore(unsigned long flags)
{
	native_restore_fl(flags);
}

static inline void native_restore_fl(unsigned long flags)
{
	asm volatile("push %0 ; popf"
		     : /* no output */
		     :"g" (flags)
		     :"memory", "cc");
}

相关延伸函数:

DEFINE_SPINLOCK(my_lock);
unsigned long flags;
spin_lock_irqsave(&my_lock, flags);	/* 先保存状态,关闭中断,然后再获取指定锁*/
/* 临界区 */
spin_unlock_irqrestore(&my_lock, flags); /* 先释放锁然后恢复状态 */

查询中断状态

in_irq()

判断当前内核是否正在执行中断处理程序,如果正在执行,则返回非0;否则返回0。

#define in_irq()		(hardirq_count())
#define hardirq_count()	(preempt_count() & HARDIRQ_MASK)

in_interrupt()

如果在中断上下文中,则返回非0;如果在进程上下文中则返回0

#define in_interrupt()		(irq_count())
#define irq_count()	(preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK \
				 | NMI_MASK))

HARDIRQ,即硬中断,其中断处理程序不可阻塞,不可重入,并且屏蔽其他中断。

Timer ticks, network cards and keyboard are examples of real hardware which produce interrupts at any time. The kernel runs interrupt handlers, which services the hardware. The kernel guarantees that this handler is never re-entered: if the same interrupt arrives, it is queued (or dropped). Because it disables interrupts, this handler has to be fast: frequently it simply acknowledges the interrupt, marks a ‘software interrupt’ for execution and exits.

SOFTIRQ,即软中断,表示可延迟执行的中断处理程序,可被阻塞,不屏蔽中断。

Whenever a system call is about to return to userspace, or a hardware interrupt handler exits, any ‘software interrupts’ which are marked pending (usually by hardware interrupts) are run (kernel/softirq.c). Much of the real interrupt handling work is done here.

NMI (non-maskable interrupt),即不可屏蔽中断。

参考:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lylhw13_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值