Subject: Re: splserial() higher than splhigh()?
To: David Querbach <querbach@realtime.bc.ca>
From: Charles M. Hannum <root@ihack.net>
List: tech-kern
Date: 02/01/2001 19:25:38
>> I believe the extremely lousy hardware in many serial controllers
>> insists on avoiding almost any latency; thus its higher priority.
...
>
> I wasn't concerned about the latency, but about mutual exclusion.  If serial
> interrupts are always enabled, the serial handlers must be very careful how
> they interact with even splhigh() code.

Yes, and if you look at the code, you'll find that it is in fact very
careful about this.

The `hard' interrupt routine only reads from a linear buffer (for
transmit) and writes to a ring buffer (for receive), and tickles a
`soft' interrupt when it needs to refill the former or empty the
latter.  This was specifically done so that the `hard' interrupt could
escape the normal splhigh()/splsched() boundary and get better
interrupt latency.

Some other systems do essentially the same thing, but with the notion
of a `fast' interrupt handler that doesn't even allow the normal
priority scheme, does stack format conversions on exit to run the soft
interrupt handler, etc.  It turns out that the mechanism I chose
worked just as well (actually, gave us better performance on many
systems) and didn't require hacking up the entire interrupt handling
system.

You'll also notice that there is a pile of code for handling
`backpressure' from the tty layer -- turning off receive interrupts in
some cases until a low water mark is reached.  Unfortunately, the tty
layer does not currently notify us of the low water mark unless
hardware or XON/XOFF flow control are also enabled, and instead the
driver goes into a mode of just throwing out everything; this is a
deficiency which should probably be fixed some day.  This could easily
be used for livelock avoidance as well.

(Yes, I really did think about all this when I wrote the code.)