2.5.68 Fix IO_APIC IRQ assignment bug
PATCH 1/1 2.5.68 Fix IO_APIC IRQ assignment bug
Looks like the fix for the "ran out of interrupt sources" panic
has a problem. It will eventually assign a device the same IRQ number as the first system vector, i.e. the local APIC timer. I think this will fix it:
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@ -1117,7 +1117,7 @
if (current_vector == SYSCALL_VECTOR)
goto next;
- if (current_vector > FIRST_SYSTEM_VECTOR) {
+ if (current_vector >= FIRST_SYSTEM_VECTOR) {
offset = (offset + 1) & 7; current_vector = FIRST_DEVICE_VECTOR + offset;
}
I found this while trying to forward-port my .66 patch to make
the redirect table look like this:
NR Log Phy Mask Trig IRR Pol Stat Dest Deli Vect:
00 001 01 0 0 0 0 0 1 1 E7 <== timer at level E 01 001 01 0 0 0 0 0 1 1 30 <== start at 30, not 31 02 000 00 1 0 0 0 0 0 0 00 03 001 01 0 0 0 0 0 1 1 38 04 001 01 0 0 0 0 0 1 1 40 05 001 01 0 0 0 0 0 1 1 48 06 001 01 0 0 0 0 0 1 1 50 07 001 01 0 0 0 0 0 1 1 58 08 001 01 0 0 0 0 0 1 1 60 09 001 01 0 0 0 0 0 1 1 68 0a 001 01 0 0 0 0 0 1 1 70 0b 001 01 0 0 0 0 0 1 1 78 0c 001 01 0 0 0 0 0 1 1 88 <== only one device at 8 0d 001 01 0 0 0 0 0 1 1 90 0e 001 01 0 0 0 0 0 1 1 98 0f 000 00 1 0 0 0 0 0 0 00 10 001 01 1 1 0 1 0 1 1 A0 11 001 01 1 1 0 1 0 1 1 A8 12 001 01 1 1 0 1 0 1 1 B0 13 001 01 1 1 0 1 0 1 1 B8 14 001 01 0 0 0 0 0 1 1 C0 15 000 00 1 0 0 0 0 0 0 00 16 000 00 1 0 0 0 0 0 0 00 17 000 00 1 0 0 0 0 0 0 00
------
Chuck
In article <[email protected]>,
Quoted 4 lines · Chuck Ebbert
Looks like the fix for the "ran out of interrupt sources" panic has a problem. It will eventually assign a device the same IRQ number as the first system vector, i.e. the local APIC timer.
Good call.
Although I suspect you need about a million interrupt sources to hit this, since FIRST_SYSTEM_VECTOR is somethign like 0xef, and thus you can hit it only when "offset" has already been incremented seven times (which implies that we've walked the whole vector space quite a few times by then).
Did you actually see this on hardware?
Anyway, applied as obvious.
Linus
Quoted 9 lines · Linus Torvalds
Good call.
Although I suspect you need about a million interrupt sources to hit this, since
FIRST_SYSTEM_VECTORis somethign like0xef, and thus you can hit it only when "offset" has already been incremented seven times (which implies that we've walked the whole vector space quite a few times by then).Did you actually see this on hardware?
Yes, we need to bail out in assign_irq_vector when we wrap around, otherwise we cause collisions when programming the IOAPIC. And we also need to avoid overruning NR_IRQS structures in setup_IO_APIC_irqs.
Zwane
In article <[email protected]>,
Quoted 3 lines · Chuck Ebbert
I found this while trying to forward-port my .66 patch to make the redirect table look like this:
Btw, why would you _want_ your redirect table to look like that?
Quoted 3 lines
NR Log Phy Mask Trig IRR Pol Stat Dest Deli Vect:
00 001 01 0 0 0 0 0 1 1 E7 <== timer at level E 01 001 01 0 0 0 0 0 1 1 30 <== start at 30, not 31
Starting at 31 is better, because..
Quoted 11 lines
02 000 00 1 0 0 0 0 0 0 00 03 001 01 0 0 0 0 0 1 1 38 04 001 01 0 0 0 0 0 1 1 40 05 001 01 0 0 0 0 0 1 1 48 06 001 01 0 0 0 0 0 1 1 50 07 001 01 0 0 0 0 0 1 1 58 08 001 01 0 0 0 0 0 1 1 60 09 001 01 0 0 0 0 0 1 1 68 0a 001 01 0 0 0 0 0 1 1 70 0b 001 01 0 0 0 0 0 1 1 78 0c 001 01 0 0 0 0 0 1 1 88 <== only one device at 8
Then we'd have devices at 81 and 89 (two per block of 16 is ok, but 80 isn't ok because we use that for system calls).
And having two devices in the 8x series means that it takes more irq sources to overflow and start to re-use the 3x block - and we want to delay re-using the 3x block as long as possible due to the silly "only one pending irq per block" rule that some intel APIC's have.
So that's why FIRST_DEVICE_VECTOR is normally 31 - because it gives a nicer pattern for the first round of allocations, and that's the common case (machines with hundreds of APIC irq sources are still rare, the common case is a single IOAPIC with 24 or so pins).
Linus