how ack() of edge-trigger IOAPIC controller prevent from irq stroms?

Submitted by ren
on October 6, 2005 - 5:02am

Hello,I have a question about how ack()of edge-trigger IOAPIC interrupt controller(struct hw_interrupt_type ioapic_edge_type) prevents from irq storms.

1827 static void ack_edge_ioapic_irq(unsigned int irq)
1828 {
1829 move_irq(irq);
1830 if ((irq_desc[irq].status & (IRQ_PENDING | IRQ_DISABLED))
1831 == (IRQ_PENDING | IRQ_DISABLED))
1832 mask_IO_APIC_irq(irq);

1833 ack_APIC_irq();
1834 }

edge-trigger IOAPIC controller does not need a message of "EOI".So ,if ack() find that irq_desc[irq].satus have a flag IRQ_PENDING and IRQ_DISABLED,it knows there are at least 2 times a device send a edge trigger through a "disabled" irq_desc channel.To prevent this device sending another interrupt,it masks(disables) the corresponding IOAPIC interrupt line.
But why ack() of level-trigger IOAPIC do nothing about irq storms?If irq_desc[irq] has been disabled,Linux kernel will also do a succssive job such as handler->ack(),tirvial job, handler->end().And when IOAPIC receive the "EOI" from handler->end(),it will send interrupt again in despite of the irq_desc[irq] is disabled.

Could anyone give me another example of irq stroms' production and how ack() doing its job?