Re: Shared edge triggered interrupts

Linus Torvalds (torvalds@transmeta.com)
Thu, 6 Aug 1998 17:13:43 -0700 (PDT)


On Thu, 6 Aug 1998, Arun Sharma wrote:
>
> On doing a net search, I found this posting of yours:
>
> > >Some system info:
> > > CPU0 CPU1 CPU2 CPU3
> > > 0: 18424 30176 149440 30416 IO-APIC-edge timer
> > > 1: 404 759 3781 761 IO-APIC-edge keyboard
> > > 2: 0 0 0 0 XT-PIC cascade
> > > 9: 8907 17891 88969 17802 IO-APIC-edge Intel EtherExpress Pro 10/100 Ethernet
> > > 10: 2284 3206 16302 3345 IO-APIC-edge aic7xxx
> > > 11: 45 3 3 8 IO-APIC-edge aic7xxx
> > > 12: 1257 2539 12729 2487 IO-APIC-edge PS/2 Mouse
> > > 13: 1 0 0 0 XT-PIC fpu
> > > 14: 3 0 0 0 IO-APIC-edge ide0
> > >NMI: 0
> > >IPI: 0
> >
> > and having shared edge-triggered interrupts is something that is very
> > obviously not ever going to work reliably (Linux could try harder to
> > make it work, but that would just make the problems happen less often
> > rather than go away completely).
>
> I would like to understand why this is so, while other operating systems
> handle it just fine.

Edge triggered shared interrupts simply do not work reliably, because you
get a setup where interrupts can get "lost" (one device starts asserting
the interrupt, and when another device comes along and asserts the same
interrupt now the other device no longer gets an "edge" at all any more.

See? You got only one edge, even though two devices accessed the
interrupt.

Now, depending on how the thing is set up, this works imost of the time.
It's never reliable, though. What can happen is:

__________________
_______/ /
^ ^ ^
A B C

At time "A", device X asserts the interrupt, and the CPU reacts to it. We
start handling the interrupt, and we have two different interrupt
handlers: one for device X and one for device Y. Let's say that we choose
to tell device Y that "hey, we got an interrupt, is it yours?" first. Now
Y will answer "no", because Y hasn't raised the interrupt and is not ready
yet.

So then we go on to device X, and ask it whether the interrupt comes from
X, and X will say "sure", and handle it, and in the meantime something
happens so that "Y" will raise it's interrupt at time "B". No edge
occurred here.

The device driver for device X is still happily handling the interrupt,
and at time C it finishes with device X, and returns. We have now handled
all shared interrupts, and the kernel returns from the interrupt handler
to normal handling.

However, the interrupt line is still active, but the CPU has never gotten
the interrupt because the edge never happened. So we'll never again see
any interrupts from Y or X, because there won't be any more edges.

In contrast, with level-triggered interrupts you don' thave any sharing
problems, because the "level" is going to remain for as long as any of the
devices assert the interrupt, so even if you didn't notice the second
device the first time around, the interrupt stays around, and we'll get an
immediate second interrupt.

Note that shared edge-triggered interrupts _do_ work most of the time. But
reliable? No.

Linus

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.altern.org/andrebalsa/doc/lkml-faq.html