Re: Race condition in tty_flip_buffer_push/flush_to_ldisc?

Stuart MacDonald (stuartm@connecttech.com)
Tue, 3 Dec 2002 11:02:12 -0500


From: "Martin Buck" <mb-kernel0212@gromit.dyndns.org>
> Suppose I'm running a serial port with low_latency enabled. The low-level
> serial interrupt handler will call tty_flip_buffer_push() which will
> immediately call flush_to_ldisc() due to low_latency being set. In
> flush_to_ldisc(), if the TTY_DONT_FLIP bit is set, it will add itself to
> the timer task queue and return. When the task queue gets processed,
> processing might get interrupted by another serial interrupt or vice
versa,
> resulting in 2 concurrent calls to flush_to_ldisc(). This time, the
> TTY_DONT_FLIP bit probably isn't set, so they both will try to process the
> same flip buffer.

What causes the DONT_FLIP bit to be un/set? I don't think your
situation can occur under normal operation. But ICBW.

> Note that reading the current flip buffer pointers isn't protected by
> cli(), only modifying them is. And even if it were, we could end up
calling
> tty->ldisc.receive_buf() twice for the same tty which probably isn't safe
> either.
>
> Any ideas on how to fix this?

If you search the lkml archive, recently Ted stated that it's
acceptable to call the line discpline's receive_buf() routine
directly, bypassing the flip buffers.

..Stu

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/