Skip to content
  • Jiri Slaby's avatar
    TTY: restore tty_ldisc_wait_idle · 100eeae2
    Jiri Slaby authored
    It was removed in 65b77046
    
     (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: default avatarJiri Slaby <jslaby@suse.cz>
    Acked-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    Tested-by: default avatarSebastian Andrzej Siewior <bigeasy@breakpoint.cc>
    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>
    Cc: stable@kernel.org [32, 33, 36]
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
    100eeae2