Subject: Re: zstty fifo overrun
To: None <chuq@chuq.com, gwr@mc.com>
From: Chris Torek <torek@BSDI.COM>
List: port-sparc
Date: 10/25/1997 14:01:15
>lower processor IPL during processing of level 14 interrupts ...

This is not a bad idea.  However, I would suggest lowering
the priority to 11, rather than 10, so that clock code gets
profiled.  It would anyway if you just forcibly lowered the
priority, but you cannot:

>... all we have to deal with is another level 14 interrupt coming in
>before we're done processing the first one

Not quite true.  Imagine the following sequence, for instance:

	1. running at ipl0
	2. L12 (zs hardware) interrupt =>
	   zshard() starts doing its thing
	3. L14 interrupt

At this point you must not lower the priority to 11 (or 10 or
anything below 12) -- you must defer the L14 interrupt until the
return-from-level-12 code returns to a level below the software
statclock level.

>all the interrupts between those levels don't modify process state

True enough, but not the real problem -- you cannot afford to take
a second L12 interrupt if you are processing an L12 interrupt
already.  You cannot even cheat with a `reentering' flag because
the hardware uses level triggered interrupts: the only way to make
forward progress while there is an existing L12 interrupt outstanding
is to keep the processor priority at 12 or higher (or disable all
interrupts entirely through the ienable register -- but this is
dangerous).

In other words, splx would need to check for deferred interrupts
at priorities greater than the new priority, and dispatch them in
those cases.  This includes `hidden' splx's in locore.s (e.g., on
the way out of the interrupt vectoring code).  Or, equivalently,
you are simulating software interrupts levels that the hardware
fails to provide.

Once you have done that, just redefine splstatclock as `spl11',
and write the statclock code as something like this:

		clear hardware interrupt;
		if (frame->priority > SOFTWARE_STATCLOCK_PRI)
			soft_pending |= 1 << SOFTWARE_STATCLOCK_PRI;
		else {
			splx(SOFTWARE_STATCLOCK_PRI);
			statclock(frame);
		}

(When you write this code you might as well add software interrupts
at all levels, hence the `1 << N'.  Of course, this forces the need
for another low-level ffs(), so maybe you could just set a variable
like "soft11_pending".)

Chris