Re: enable_ioapic_irq broken in arch/i386/kernel/irq.c

MOLNAR Ingo (mingo@chiara.csoma.elte.hu)
Sun, 26 Apr 1998 19:11:02 +0200 (CEST)


On Sat, 25 Apr 1998, Linus Torvalds wrote:

> I've made some other changes in my tree already, I always found the
> repeating and counting to be of dubious value - if we have nested
> interrupts there is no point in trying to count them up. 2.1.98 makes one
> counter be a simple flag, and I think the other counters should be simple
> flags too.

the 'counter' thing was necessary because the ioapic code never masked
interrupts like the UP version did. This was a design decision because
documentation suggested we should not handle the IO-APIC as a simple state
machine with 'IRQs on/off' states, but rather like a unit emitting IRQ
events. I first tried to use the IO-APIC 'IRQ on/off' feature and found it
is completely unreliable, ie. one cannot be sure from what point on a
device-side IRQ line is being ignored. (there is an about 10 usecs delay
which makes sure no APIC transaction is pending, but even this delay is
sometimes inadequate)

The 'old' PIC masks incoming IRQs in sync with the CPU. (this is also one
reason why it's slower, but it works)

worse, no other OS seems to do the 'quick ACK' thing we do, thus it's
quite dangerous to rely even on the documented 'IRQ disable' feature of
the IO-APIC. Most other OSs seem to ACK the local APIC only when the
handler has finished ... this nicely serializes the APICs but is
unacceptable for Linux.

so i gave up and left all IO-APIC irq lines enabled always, and added the
counter to shield the CPU side from this. In this design, the counter
_does_ make sense even when there are no APIC weirdnesses, eg. when there
are shared PCI devices on the same IRQ line.

the 'counter thing' is simply an implementation for masked interrupts,
when the hard interrupts are not masked themselves.

and this model worked remarkedly well. (there were some spurious reports
of 'runaway' interrupt lines, where a rouge line created IRQ storms, but
most of these were mptable parsing errors, treating level-triggered
devices as edge triggered ones is a fatal mistake). The IDE/SCSI anomalies
(and the PS2 mouse thing) were all i think caused by the erroneous
disable/enable_irq() implementation (which never was so bad that it showed
up on my system, but it certainly caused problems for other people). So i
added the send_IPI() thing to fix this final major (known) ugliness, but
it didnt work yet under very heavy IRQ load, it looked like typical APIC
errata. (fortunately i have an ancient SMP system, with all the APIC
erratas at hand :).

so my plan was this before the IOAPIC part of irq.c was turned upside
down:

- fix the send_IPI() thing to get 100% compatible en/disable_irq()
- fix spurious mptable parsing errors still preventing some
systems from booting cleanly

we had _all_ those bugs, floppy.c hang, SCSI hangs and many more bugs, all
fixed along the way from 2.1.48 to 2.1.96 :)

-- mingo

ps. the send_IPI() thing is i think better than anything else, since it's
a rare event, has limited latency and saves us an if() in global_cli/sti.
(the CPU does it for us).

checking for pending IRQs in the 'next' IRQ (suggested by someone) is not
quite robust.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu