Subject: interrupt masking
To: None <port-i386@netbsd.org>
From: T. William Wells <bill@twwells.com>
List: port-i386
Date: 09/18/1994 13:27:02
In doing my fast interrupt code, I attempted to just re-enter the normal
interrupt code, when the fast interrupt indicated that the slow code was to
be executed.  That was a loser.

That regular interrupt code masks and unmasks the interrupt, which means that
the fast handler is locked out while the slow handler is executing, NOT the
intended behavior!

On thinking about how to get around this, the question occured to me: why
mask them at all? This is my understanding of what happens when an interrupt
comes in, ignoring some irrelevancies:

      o Mask this interrupt in the ICU.
      o If cpl has this interrupt's pl set, set ipending and return.
(resume point)
      o Save the current cpl.
      o Set pl bits in cpl for this interrupt.
      o Permit interrupts.
      o Call interrupt handler(s).
      o Unmask the interrupt
(doreti)
      o Restore the saved cpl
      o If there are any pending interrupts allowed,
      o         Clear the pending bit.
      o         Branch to the resume point for the interrupt.
      o Return from the interrupt

If I understand this, the effect of masking the interrupt is to prevent it
from re-occuring while the handler is active. However, the cpl&ipending test
does the same thing. (Actually, if I'm reading the code right, the ipending
bits aren't ever set because of an interrupt on the same channel; they're set
because of an interrupt on a *different* channel that uses the same spl*.)

Removing the mask would permit interrupts while the handler was executing,
which would be recorded in ipending, and then handled in doreti.

In fact, the mask only has the effect of preventing recursive interrupts
during the handler call itself, as other recursive interrupts are dealt with
by other means. And, at that, it isn't entirely effective.

Consider an interrupt just after the unmask and before the cpl is restored.
That will cause a pending bit to be set, which will cause doreti to go to the
resume point and then execute the handler with the interrupts unmasked.

As near as I can tell, the *only* time masking should matter is for an
interrupt handler that actually fiddles with the ICU, as otherwise the
difference between an interrupt masked by ipending and one masked in the ICU
is invisible. And no interrupt handler should do that!

Comments?