Re: PROBLEM: Race condition in tty buffer's functionflush_to_ldisc().

From: Alan Cox
Date: Mon Nov 07 2011 - 07:55:41 EST


> if (!test_and_set_bit(TTY_FLUSHING, &tty->flags)) {
> .....
> } else
> prink...
> In my syslog appear this prink on pty devices.

Then we need to understand the call paths that did this. I suspect it
may be a bug in the hacks Linus made to n_tty. They've always bothered
me as they never looked correct.

Can you get traces to see if it is actually calling flush_to_ldisc
multithreaded on a given tty

> Why we need: "if (!test_and_set_bit(TTY_FLUSHING, &tty->flags)) {"
> if flush_to_ldisc is single threaded?
> we can: set_bit(TTY_FLUSHING, &tty->flags)
> without if() at all.

It is single threaded with respect to itself (you can't have two
flush_to_ldisc on the same tty at once) but you can have a parallel
call to tty_buffer_flush. The tty_buffer_flush path needs to pick the
right approach reliably.

So the theory is

If TTY_FLUSHING is set then tty_buffer_flush lets the flush_to_ldisc do
the work. During this time we won't fluish a buffer under the ldisc.

If TTY_FLUSHING is not set then we will do the flush directly. As we
hold tty->buf.lock at that point the two cannot race as far as I can
see.

We are actually now probably at the point we could take a per tty mutex
on the flush_to_ldisc and use it to tidy up ldisc change, flush and
other things. So this code could welll be something worth simplifying
once the rest of the tty_lock() is cleaned out.

Alan
--
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/