我正在尝试了解 Linux 中断处理机制。我试着用谷歌搜索了一下,但找不到这个问题的答案。有人可以向我解释为什么 handle_IRQ_event 最后需要调用 local_irq_disable 吗?在此之后,控制返回到 do_irq,它最终将返回到入口点。那么谁来启用中断呢?它是中断处理程序的责任?如果是这样,为什么会这样?
编辑
引用代码
asmlinkage int handle_IRQ_event(unsigned int irq, struct pt_regs *regs, struct irqaction *action)
{
int status = 1;
int retval = 0;
if (!(action->flags & SA_INTERRUPT))
local_irq_enable();
do
{
status |= action->flags;
retval |= action->handler(irq, action->dev_id, regs);
action = action->next;
}
while (action);
if (status & SA_SAMPLE_RANDOM)
add_interrupt_randomness(irq);
local_irq_disable();
return retval;
}
最佳答案
来自 LDD3 的 handle_IRQ_event
版本似乎来自 2.6.8 内核,或者可能更早。假设我们正在处理 x86,处理器在调用中断处理程序之前清除 EFLAGS 寄存器中的中断标志 (IF)。旧的 EFLAGS 寄存器将由 iret
指令恢复。
Linux 的 SA_INTERRUPT
IRQ 处理程序标志(现已过时)确定中断处理程序中是否允许更高优先级的中断。 SA_INTERRUPT
标志设置为“快速”中断处理程序,使中断处于禁用状态。 SA_INTERRUPT
标志未设置为重新启用中断的“慢速”中断处理程序。
无论 SA_INTERRUPT
标志如何,do_IRQ
本身都在禁用中断的情况下运行,并且在调用 handle_IRQ_event
时它们仍然被禁用。由于 handle_IRQ_event
可以启用中断,最后调用 local_irq_disable
确保它们在返回到 do_IRQ
时再次被禁用。
i386架构的2.6.8内核中的相关源代码文件是arch/i386/kernel/entry.S
,和arch/i386/kernel/irq.c
.
关于linux-kernel - Linux 中断处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35423063/