Re: ASM1083 PCIx-PCI bridge interrupts - widespread problems

From: Jeroen Van den Keybus
Date: Thu Feb 02 2012 - 17:42:16 EST

>> And we'd probably need to limit the warning messages if we start
>> re-enabling it - so that people with constantly screaming interrupts
>> don't get a constant stream of 10 "nobody cared, disabling" messages
>> per second.

Main reason for the patch to comment out __report_bad_irq(). There's
other printk's in there right now, allowing monitoring of the patch's
(hack's) performance. After 2 months of testing, the following is a
typical result on my Asus E45M1-M board:

[1675739.482843] Disabling IRQ 16
[1675739.488056] Polling IRQ 16
[1675740.288244] Reenabling IRQ 16
[1675740.288363] Disabling IRQ 16
[1675740.296132] Polling IRQ 16
[1675802.512233] Polling IRQ 16
[1675803.312244] Reenabling IRQ 16
[1675803.312362] Disabling IRQ 16
[1675803.320233] Polling IRQ 16
[1675804.120229] Reenabling IRQ 16

Because this particular IRQ is only asserted once every 64 s, polling
mode stays active for that amount of time, until a new INTx Deassert
is received. So it appears that INTx Deassert is not delayed, but
simply lost (either not sent or not received by the IO-APIC).

I did a test ( in which I
programmed an e1000 to issue one of the interrupts it doesn't use/need
(RXT0). From that log, it is clear that raising and clearing the IRQ
after more than 60 µs did not generate the expected INTx Deassert
either. There is serious trouble with this device.

> * New logic in the generic IRQ code, in spurious.c, adding a "try
> polling, then re-enable for
> a while" method, for everybody?

Something like it (poll for a while, then try reenabling). Please see
the patch ( for the general idea.

> * Could there be more hardware-specifc code, to crank up the
> frequency, when you do have this chip? I don't think we have this
> facility at present: would we let the arch-or-drivers code set a
> variable, to be honored by irq/spurious.c?

I would propose to crank up the frequency adaptively. Whenever
reenabling fails (i.e. is followed by a storm immediately), the
poll_spurious_irq_timer interval may be increased gradually up to,
say, 100ms (the value currently used by irqpoll). In the other cases,
it could be decreased progressively to e.g. 1 ms. So add or subtract
one ms of polling time whenever reenabling fails or succeeds,
respectively. Attempt to reenable an IRQ could occur after a fixed
amount of polling cycles (100).

Alternatively, the interval could also be modified by the number of
interrupts received in an interval.

- When, Heaven forbid, more than one IRQ is handled by this mechanism,
what would the polling interval need to be ? The shortest of them all
? Can/should timers be created dynamically ?
- Would struct irq_desc be an appropriate place to keep the per-irq
variables to accomplish all this ? I noticed that there is also
- Are there any alignment/security requirements on struct irq_desc to
be aware of ?
- Alan Cox also suggested that IRQ 0 'magic' could be an issue. I
cannot really find what he refers to in spurious.c, but it may be
important ?
- Are there any drivers that would not be able to operate in a polling fashion ?

To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at
Please read the FAQ at