diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-10-14 08:59:49 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-10-22 15:12:01 -0700 |
commit | 86d23a057e718f73adc15e463c643d6e014a19cd (patch) | |
tree | 43c24d7a1ad37dca244dc4a07135a42e9c280c67 /Documentation/s390 | |
parent | c90aa19d5123cc84fe2260067a3348313349d262 (diff) |
tty: Make flush_to_ldisc() locking more robust
commit c8e33141911bf8fe87dc6c92793b9a59b2be0130 upstream.
The locking logic in this function is extremely subtle, and it broke
when we started doing potentially concurrent 'flush_to_ldisc()' calls in
commit e043e42bdb66885b3ac10d27a01ccb9972e2b0a3 ("pty: avoid forcing
'low_latency' tty flag").
The code in flush_to_ldisc() used to set 'tty->buf.head' to NULL, with
the intention that this would then cause any other concurrent calls to
not do anything (locking note: we have to drop the buf.lock over the
call to ->receive_buf that can block, which is why we can have
concurrency here at all in the first place).
It also used to set the TTY_FLUSHING bit, which would then cause any
concurrent 'tty_buffer_flush()' to not free all the tty buffers and
clear 'tty->buf.tail'. And with 'buf.head' being NULL, and 'buf.tail'
being non-NULL, new data would never touch 'buf.head'.
Does that sound a bit too subtle? It was. If another concurrent call to
'flush_to_ldisc()' were to come in, the NULL buf.head would indeed cause
it to not process the buffer list, but it would still clear TTY_FLUSHING
afterwards, making the buffer protection against 'tty_buffer_flush()' no
longer work.
So this clears it all up. We depend purely on TTY_FLUSHING for handling
re-entrancy, and stop playing games with the buffer list entirely. In
fact, the buffer list handling is now robust enough that we could
probably stop doing the whole "protect against 'tty_buffer_flush()'"
thing entirely.
However, Alan also points out that we would probably be better off
simplifying the locking even further, and just take the tty ldisc_mutex
around all the buffer flushing calls. That seems like a good idea, but
in the meantime this is a conceptually minimal fix (with the patch
itself being bigger than required just to clean the code up and make it
readable).
This fixes keyboard trouble under X:
http://bugzilla.kernel.org/show_bug.cgi?id=14388
Reported-and-tested-by: Frédéric Meunier <fredlwm@gmail.com>
Reported-and-tested-by: Boyan <btanastasov@yahoo.co.uk>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: Paul Fulghum <paulkf@microgate.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'Documentation/s390')
0 files changed, 0 insertions, 0 deletions