Linux Interrupt Handling

谁说胖子不能爱 提交于 2019-12-22 13:49:46

问题


I am trying to understand the Linux interrupt handling mechanism. I tried googling a bit but couldn't find an answer to this one. Can someone please explain it to me why the handle_IRQ_event needs to call local_irq_disable at the end? After this the control goes back to do_irq which eventually will go back to the entry point. Then who will enable the interrupts back.? It is the responsibility of the interrupt handler? If so why is that so?

Edit

Code for reference

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; 
}

回答1:


The version of handle_IRQ_event from LDD3 appears to come from the 2.6.8 kernel, or possibly earlier. Assuming we're dealing with x86, the processor clears the interrupt flag (IF) in the EFLAGS register before it calls the interrupt handler. The old EFLAGS register will be restored by the iret instruction.

Linux's SA_INTERRUPT IRQ handler flag (now obsolete) determines whether higher priority interrupts are allowed in the interrupt handler. The SA_INTERRUPT flag is set for "fast" interrupt handlers that left interrupts disabled. The SA_INTERRUPT flag is not set for "slow" interrupt handlers that re-enable interrupts.

Regardless of the SA_INTERRUPT flag, do_IRQ itself runs with interrupts disabled and they are still disabled when handle_IRQ_event is called. Since handle_IRQ_event can enable interrupts, the call to local_irq_disable at the end ensures they are disabled again on return to do_IRQ.

The relevant source code files in the 2.6.8 kernel for i386 architecture are arch/i386/kernel/entry.S, and arch/i386/kernel/irq.c.



来源:https://stackoverflow.com/questions/35423063/linux-interrupt-handling

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!