hardware based IRQ routing on Intel SMP boxes, 2.1.76 patch

MOLNAR Ingo (mingo@chiara.csoma.elte.hu)
Mon, 29 Dec 1997 00:03:29 +0100 (CET)


The attached 2.1.76 patch activates Intel MP 1.1/1.4 'SMP Symmetric IO
mode', and implements SMP irq routing through the IO-APIC, by extending
Linux's current irq handling scheme, (almost...) seemlessly to drivers.
NR_IRQS is increased from 16 to 24, an irq line can be either IO-APIC
generated or INTA generated, switchable at compile time. All important
irqs are routed through the IO-APIC, they are forwarded in 'lowest
priority' delivery mode, the least busy CPU is selected for handling an
individual hardware IRQ. All CPUs are thus handling external irqs, in
parallel.

the biggest difference to 'stock' Linux irq handling is that APIC/INTA
interrupts are no more masked off when entering do_IRQ(). The irq routing
hardware is designed in a way that seems to make it impossible to keep the
'old' Linux irq handling scheme in a sane way. I've tried hard, but had to
give up ... This patch software-enforces that IRQ handlers are atomic to
themselves.

(there are some known weaknesses: enable/disable_irq() is not quite
correct in it's current form. [The main reason for this is that our
current global_cli() 'drops' irq context information temporarily, which
makes it hard to _really_ wait for all irq contexts to finish executing.
Irq contexts might be waiting in get_irqlock(), having all their context
info dropped temporarily, deceiving disable_irq().] Uniprocessor kernels
are not working currently.)

The patch is stable on my box, things like mass flood pinging and massive
harddisk load did not cause any problems, but the patch should still be
considered experimental. I'm curious wether the patch actually boots on
other machines, and wether it shows the same speedups as on my box ;) The
patch includes some multi-CPU-irq-handling related 8390.c and ide.c fixes
as well. [my NE2000 finally works under SMP ;)]

/proc/interrupts is extended to display per-CPU irq counts and interrupt
line modes:

CPU0 CPU1
0: 68659 0 XT PIC timer
1: 4267 2917 IO-APIC keyboard
2: 0 0 XT PIC cascade
4: 8 6 IO-APIC serial
9: 25388 16975 IO-APIC NE2000
13: 4 0 XT PIC fpu
14: 101230 114714 IO-APIC ide0
NMI: 0
IPI: 0

[The patch also streamlines/simplifies some more SMP code, gets rid of
SMP_PROF #ifdefs, etc. I think /proc/interrupts is sufficient and simpler
to support, but no strong feelings either way.]

It would be nice if people could comment on the solutions in irq.c,
especially the do_IRQ()/handle_IRQ_event() concepts, i'm curious how
things like disable_irq() could be implemented in a sane way, and wether
the new IRQ ACK semantics work with all hardware configurations.

Comments, reports, suggestions more than welcome, let me know if i've
missed something.

-- mingo

begin 664 io-apic-patch-2.1.76-B.gz
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
2\LE5P<N6GKO_`Y@7-_'"K0``
`
end