Re: Help needed on Serial driver issues

Theodore Y. Ts'o (tytso@MIT.EDU)
Wed, 21 Jan 1998 14:49:35 -0500


Date: Wed, 21 Jan 98 10:47:29 -0500
From: Shashi Ramamurthy <sramamurthy@equinox.com>

At this point I started to look at the kernel source (tty_io.c and
n_tty.c) and saw that it was possible to lose data when
"flush_to_ldisc" (tty_io.c) calls "tty->ldisc.receive_buf" and never
really checks the "count variable" to see how much has been written to
tty->read_buf buffer. Here's the code for our receive char routine,

Yes, this is correct. The kernel buffer is only so big, and if you
continually pump data into it, eventually it has to spill out
somewhere. :-)

(I mean, you could allocate additional kernel memory as more data came
in, but that would be an easy way to perform a denial of service attack
by flooding a system with too much data until all kernel memory got
allocated, and then the system falls over. Ultimately, if the other
side isn't paying attention to the flow control, and continues to send
you data, at some point you have got to put your foot down....)

My guess is that either (a) your customer hasn't configured flow
control, or (b) the system your customer hasn't configured flow control,
or (c) your driver isn't supporting flow control. When the read_buf
buffer gets close to overflowing, the line discipline calls
tty->driver.throttle(tty). The device driver is supposed to then do the
appropriate flow control thing (either send an immediate XOFF character,
or lower RTS, depending on how termios is set).

The line discpline is set up to send the throttle message when there is
128 bytes of space left in the 1k buffer. If flow control is not
enabled, or the driver doesn't implement the throttle method, or the
customer's communications partner ignores the request to stop sending
characters, then 128 characters later, characters will indeed get
dropped on the floor. But that's not the kernel's fault. :-)

Are you sure that problem is caused by read_buf actually overflowing?
As I've said several times now, assuming that flow control is properly
implemented and configured, read_buf should not be overflowing. If
you're using a polling driver, the most likely cause is that when the
system is getting heavily loaded, the your polling driver isn't getting
called fast enough to prevent characters from getting lost from the
Equinox's internal buffer/FIFO. How big are the Equinox's internal
buffers for each port? The Comtrol Rocketport has a 1024 byte receive
FIFO, and I've never had a problem reported with characters being
dropped, even under heavy load.

- Ted

P.S. My apologies for not responding right away; I've been out of town
until late last night. So when I don't respond right away, you might
want to wait a day or two before deciding to time out and send mail to
linux-kernel.