Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 30 Jun 1996 02:41:45 +1000
From:      Bruce Evans <bde@zeta.org.au>
To:        bde@zeta.org.au, chuckr@Glue.umd.edu
Cc:        freebsd-hardware@FreeBSD.org
Subject:   Re: muliport boards - building a PPP dialup server
Message-ID:  <199606291641.CAA11012@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help

>> >As you know once you're in the interrupt routine it will
>> >check all ports, meaning that in the special case of input streaming
>> >in on multiple ports you will have a big reduction in interrupt load.
>> >I second looking up some of Bruce's postings.
>> 
>> This is actually the weakest point in the sio driver.  Polling 16
>> ports wastes a lot of time when only a few of them are active, and
>> I think processing multiple ports per interrupt is relatively rare
>> even when many of them are active.  The poll is only for interrupt-
>> pending, not for input-available so it only finds input when the
>> the fifo is full.

>Are you sure of that, Bruce?  I spoke a long while back with a guy who'd 
>written the digiboard driver for sysV machines, and he claimed that, 
>except when only one port was active, that it was actually much more 
>efficient to ignore which uart had actually issued the interrupt, and 
>simply service them all on each interrupt.  He said he'd done some 
>testing to back that up, altho I don't have the specifics anymore (this 
>was at least 5 years ago).

Fairly sure.  I'm fairly sure that for an 8 port cyclades board on a
486/33 it is most efficient to process precisely the ports which have an
interrupt pending.  Looking inside the UARTs on a cd1400 is very
expensive.  Although the chip has a lot of directly accessible memory-
mapped registers, the critical registers have to be bank switched to do
i/o.  A naive polling method (like the one in the data book :-) takes 16
i/o's per port for bank switching and 3 i/o's per port to poll for the
existence of a serial event (input, input exception, modem status change
or output completion).  This could possibly be reduced to 4 i/o's per
port by not preserving the registers.  I didn't even consider polling
everything for the cyclades driver!

What I tested carefully was looping until all pending interrupts (for
the cyclades board that interrupted) were serviced.  Looping costs only
one i/o per cd1400 (2 i/o's for an 8-port board), but was slower because
it rarely found anything to do and taking an extra interrupt only costs
a few usec (and if polling was cheaper and used, finding something to do
would often be bad because of high setup costs).  The 16550 multiport
driver has to loop to (portably) avoid ISA edge triggered interrupt
braindamage.

Looking inside a 16550 is only fairly expensive.  It takes 2 i/o's to
poll for the existence of a serial event.  I think this is about 2 too
many for polling to be worthwhile :-).  Taking an extra interrupt costs
5-10us on a 486DX2/66, so always doing 2 extra i/o's at a cost of 1.25us
each is only worthwhile if it finds something to do more than 50%-25%
of the time.

OTOH, the SysV optimization is close to being best for the first time
around the loop in the 16550 multiport case.  The loop currently takes 
1 i/o per port to poll for pending interrupts (this misses partially
full fifos).  The two i/o's for a full poll could be reduced to 1 if
the polling for modem status change is skipped.  Modem status changes
could be checked for only if there didn't seem to be any other cause
for the interrupt.  The loop to test for pending interrupts would still
be necessary on systems with edge triggered interrupts.  8250s and
some 16450s lose modem status interrupts, so this method should only
be used if it works.

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199606291641.CAA11012>