Re: Serial driver hangs

From: Roland CaÃebohm
Date: Thu Sep 30 2004 - 11:22:03 EST


Am Mittwoch, 29. September 2004 16:25 schrieb Paul Fulghum:
> On Wed, 2004-09-29 at 09:07, Roland CaÃebohm wrote:
> > I have added a routine to "struct tty_driver" for
> > restarting the RX interrupt after TTY_DONT_FLIP bit is
> > cleared in read_chan().
>
> If you are using RTS/CTS flow control,
> your scheme might prevent data loss if you also
> drop RTS (like driver throttle method) when disabling
> the rx IRQ and reasserting RTS (unthrottle) when
> reenabling the IRQ. Unfortunately, this may interfere
> with the line discipline's use of throttle/unthrottle.

Maybe I can use the functions rs_throttle() and
rs_unthrottle(). In rs_unthrottle I could reenable the RX
interrupt. So I don't need to add a function in "struct
tty_driver". I only need to set the flag TTY_THROTTLED if I
disable the interrupt.

>
> > It seems to take to long time in read_chan(). Do you now
> > what is the exact reason of locking the filp buffer with
> > the TTY_DONT_FLIP flag? For a short look I would say the
> > buffers are safe locked by the spinlock tty->read_lock.
>
> I can't identify the reason.
> If you feel brave, remove the setting/clearing
> of TTY_DONT_FLIP and see what happens.

I've just commented out all places where TTY_DONT_FLIP would
be set and left everything else original. It seems to work
without problems.

My system is sending and receiving on two ports with 921600
baud with CPU load of 85%. Some bytes get still lost, but
less then before. The test is working for 2h now and I have
forced sometimes some more activity to have a CPU load of
100%, but it is still working.

Maybe TTY_DONT_FLIP is really don't needed anymore.
I think to be save and fast maybe one way could be, if the
flip buffer is full it should be flipped but not processed
with tty->ldisc.receive_buf() in the interrupt routine.
flush_to_ldisc() has then always to look at both flip buffers
and process them.
If the second flip buffer is still not clean, if the interrupt
routine needs to flip it, it has to stop the flow and disable
the receive interrupt.
unthrottle() could then reenable the interrupt.

Maybe my thinking is to simple, what do you think?

Roland
--
___________________________________________________

VS Vision Systems GmbH, Industrial Image Processing
Dipl.-Ing. Roland CaÃebohm
Aspelohe 27A, D-22848 Norderstedt, Germany
Mail: roland.cassebohm@xxxxxxxxxxxxxxxx
http://www.visionsystems.de
___________________________________________________
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/