Subject: Re: com driver troubles on NetBSD/i386
To: None <Chris_G_Demetriou@UX2.SP.CS.CMU.EDU, bouyer@ensta.fr>
From: Bruce Evans <bde@zeta.org.au>
List: current-users
Date: 05/25/1996 05:30:09
>The notion of running the 'com' interrupt handler at IPL_HIGH makes
>little or no sense on machines where interrupt levels aren't as
>flexible as they are on the i386.

>On all Alphas i've seen so far:
>	(1) there's no way to reassign the interrupt priority for a
>	    given device,
>	(2) all devices interrupt with the same priority level.

>I can't easily change either of those facts, and neither can i easily
>implement an ICU management scheme like the i386 port does, because

The i386 port doesn't really use the (in)flexible interrupt levels
provided by the ICU.  It goes to some trouble to replace the ICU levels
by software levels as soon as possible after an interrupt occurs.  It
depends on the ICU to implement masking of the interrupts that you don't
want to be bothered by.  This masking can be done using device registers
for some other systems/devices (probably a little further into the
interrupt handler).

>...

>What this means is that these changes would actually _HURT_ serial
>performance on the Alpha (probably to the point of making high-speed
>communication impossible without hardware flow control).  The problem
>is a simple one:

>	These changes enqueue data at "high priority" for later
>	processing, and that later (character input) processing
>	happens at IPL_TTY. 

>On the Alpha, both "high priority" and IPL_TTY _have_ to block 'com'
>device interrupts (the former because that's what's meant by high
>priority, the latter because there's only one device interrupt level,
>and there could be other serial devices in the system).

>It should be obvious why this loses badly.

Can you mask interrupts after they occur, at an acceptable cost?  Then
IPL_TTY can mask certain tty device interrupts (not including com
interrupts) in software until one actually occurs, more or less like
it does in the i386 port.  It is almost possible to make IPL_TTY ==
the softclock ipl.  This is sort of what it used now for blocking
reentry into the l_rint() routine for com devices.  It doesn't quite
work in general because some tty devices don't use double buffering.
For the i386 port, the cost of delaying blocking of interrupts is
typically -0.5 us (average) because i386's are much faster than buses
and ICUs.

Handling multiple "high priority" serial/other devices is more
interesting.  The "high priority" interrupt method only works perfectly
for one "high priority" device.   It works for a multiple ones if the
worst-case interrupt latency is small enough.  If the latency from
random ordering of the interrupts is too high, the only hope is to treat
all the "high priority" devices as one super-device and enter some sort
of prioritized polling mode to access it (poll the most needy device
next, and somehow avoid spending too long on any one device).  Low
priority devices can be handled in the same mode.  This method works
on any system with pollable devices and at least zero levels of
interrupt priorities (no interrupts).  It may even be the best possible
method, given a fast method of polling (all devices at once) and one
level of interrupt priorities (enable/disabled).

Bruce