Re: serial flow control appears broken

Russell King
2007-07-28T09:29:23Z

On Fri, Jul 27, 2007 at 12:22:57PM -0600, Robert Hancock wrote:
> Maciej W. Rozycki wrote:
> > The TTY line discipline driver could do that based on the amount of
> >received data present in its buffer. And it should if asked to (a brief
> >look at drivers/char/n_tty.c reveals it does; obviously there may be a bug
>
> Really, where? In my look through the code I haven't found any mechanism
> that would result in RTS being lowered based on TTY buffers filling up,
> at least not in the 8250 case.

That's something for the line discipline to decide.

> In this situation, though, it appears it's not the TTY buffers that are
> filling but the UART's own buffer. I would think this must be caused by
> some kind of interrupt latency that results in not draining the FIFO in
> time.

Correct, and suggested approach to tracking down the culpret has been
mentioned in a previous email.

Also note that there's nothing the serial driver can do to detect this
condition before it occurs. The problem occurs because the serial driver
is starved of CPU time due to other parts of the system, and the driver
has precisely zero knowledge as to when that's going to happen.

There are two possible scenarios when such starvation can occur:

1. interrupts are disabled for a long period.
2. the serial interrupt has started to run, but has been interrupted
by _another_ interrupt which runs for a long period.

Essentially, any complex interrupt handler (such as an IDE interrupt
doing a multi-sector PIO transfer _in interrupt context_) can cause this
kind of starvation. That's why Linux 1.x had bottom halves - so that
the time consuming work could be moved out of the interrupt handler,
thereby causing minimal the blockage of other interrupts.

Unfortunately, that kind of design has been long since forgotten.
Apparantly modern machines are fast enough that it doesn't have to be
worried about anymore... Or are they?

--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/