Da Zheng, le Wed 12 May 2010 17:36:36 +0800, a écrit :
On 10-5-12 上午6:03, Samuel Thibault wrote:
Da Zheng, le Sat 08 May 2010 23:19:08 +0800, a écrit :
A stupid question: when disable_irq_nosync is called, IRQ_DISABLED is set in the irq descriptor in the Linux kernel and the corresponding hardirq line should be masked as well (at least, it seems the kernel for x86 does so).
AIUI, on unmask the hardware will trigger the interrupt that was raised by the hardware in the meanwhile. Which precise x86 file are you looking at? What do you exactly mean by "hardirq": the actual hardware chip or the software hardIRQ handler?
In disable_irq_nosync, there is code as follow: desc->status |= IRQ_DISABLED; desc->chip->disable(irq); For the x86 platform, `disable' points to disable_8259A_irq. So when disable_irq_nosync is called, IRQ_DISABLED is set and the irq line (the hardware) is masked.
Yes.
How can handle_edge_irq be called?
AIUI, on hardware irq unmasking.
When hardware irq is unmasked, IRQ_DISABLED should have been removed. I meant, how can handle_edge_irq be called when IRQ_DISABLED is still set? It seems to me that IRQ_PENDING cannot be set in handle_edge_irq when the irq line is disabled.
?
if (unlikely((desc->status & (IRQ_INPROGRESS | IRQ_DISABLED)) || !desc->action)) { desc->status |= (IRQ_PENDING | IRQ_MASKED); mask_ack_irq(desc, irq); goto out_unlock; }
So here, even if IRQ_DISABLED is not cleared before the hardware chip part is unmasked, IRQ_PENDING flag will be set.
Samuel