]> git.karo-electronics.de Git - karo-tx-linux.git/commit
TTY: restore tty_ldisc_wait_idle
authorJiri Slaby <jslaby@suse.cz>
Sun, 31 Oct 2010 22:17:51 +0000 (23:17 +0100)
committerAndi Kleen <ak@linux.intel.com>
Tue, 14 Dec 2010 22:40:08 +0000 (23:40 +0100)
commit7a4239f949215adc0f5271cb176c48aafbe9a71e
tree8b634047b35e0e015a4acce235fb543b003000e7
parente14e0aafc584d46b128301bcf399f2dd6e6d2cc7
TTY: restore tty_ldisc_wait_idle

commit 100eeae2c5ce23b4db93ff320ee330ef1d740151 upstream.

It was removed in 65b770468e98 (tty-ldisc: turn ldisc user count into
a proper refcount), but we need to wait for last user to quit the
ldisc before we close it in tty_set_ldisc.

Otherwise weird things start to happen. There might be processes
waiting in tty_read->n_tty_read on tty->read_wait for input to appear
and at that moment, a change of ldisc is fatal. n_tty_close is called,
it frees read_buf and the waiting process is still in the middle of
reading and goes nuts after it is woken.

Previously we prevented close to happen when others are in ldisc ops
by tty_ldisc_wait_idle in tty_set_ldisc. But the commit above removed
that. So revoke the change and test whether there is 1 user (=we), and
allow the close then.

We can do that without ldisc/tty locks, because nobody else can open
the device due to TTY_LDISC_CHANGING bit set, so we in fact wait for
everybody to leave.

I don't understand why tty_ldisc_lock would be needed either when the
counter is an atomic variable, so this is a lockless
tty_ldisc_wait_idle.

On the other hand, if we fail to wait (timeout or signal), we have to
reenable the halted ldiscs, so we take ldisc lock and reuse the setup
path at the end of tty_set_ldisc.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Tested-by: Sebastian Andrzej Siewior <bigeasy@breakpoint.cc>
Signed-off-by: Andi Kleen <ak@linux.intel.com>
LKML-Reference: <20101031104136.GA511@Chamillionaire.breakpoint.cc>
LKML-Reference: <1287669539-22644-1-git-send-email-jslaby@suse.cz>
Cc: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/char/tty_ldisc.c