From: Linus Benedict Torvalds (torvalds@klaava.Helsinki.FI)
Date: 07/21/92


From: torvalds@klaava.Helsinki.FI (Linus Benedict Torvalds)
Subject: Re: Better serial throughput: another approach
Date: 21 Jul 1992 20:18:58 GMT

In article <2A6C23D4.5D7F@tct.com> chip@tct.com (Chip Salzenberg) writes:
>According to hedrick@dumas.rutgers.edu (Charles Hedrick):
>>I've finally concluded that there's just too much code being
>>executed per character.
>
>There is another way, as SCO does:
>
> At serial interrupt: just store the character in a queue and return.
> Don't go through scheduler, just return.
>
> At clock interrupt: pull characters off the queues and do the rest
> of the processing that is currently happening at serial interrupt
> time. Then run the scheduler, _once_.
>
>Presto: minimum-overhead serial I/O.

This is in fact how linux does it already: the problem has been to find
the offending code. As I haven't actually seen the character loss, I
originally thought it was either bad interrupt latency or simply too
slow serial interrupt routines. After more testing (mainly thanks to
hedrick), it seems the problem is actually the clock interrupt routine:
it's too slow.

"Why would the system care how slow the clock interrupt is?" - the
reason is simple: interrupts are enabled while the serial interrupt
happens, so the following can happen:

        serial interrupt received: handler started
                timer interrupt received: immediate response
                timer interrupt does the serial copying, returns
        serial handler returns.
        
The result is that while the serial code is fast enough, it can get
interrupted by the timer interrupt (which happens 100 times a second:
not too surprising if it happens while the serial handler is active
every now and then).

The timer interrupt isn't that complicated, but it does do the
copy_to_cooked routine, which can take some time. So, there are four
possibilities: (a) make the serial interrupt handler atomic or (b) speed
up the copy_to_cooked routine or (c) move copy_to_cooked from within the
timer-interrupt to some less time-critical place and (d) rewrite the
general tty handlers totally to have less need for the copy-to-cooked
routines.

I'm in fact looking into all four possibilities, and 0.97 will contain
one or several of the fixes. One way of getting slightly better
performance already is to use the patch by hedrick, which essentially
speeds up copy_to_cooked by making some of the help-function inline etc.

[ Note that you cannot right now use SA_INTERRUPT to install a serial
handler that is totally atomic: it's still interruptible in the general
IRQ handling code. I'll have to change this for the next version
anyway, as the old problems with some (buggy?) harddisks are back ]

                Linus