Commit 0b5759c6 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

tty: Avoid dropping ldisc_mutex over hangup tty re-initialization

A couple of people have hit the WARN_ON() in drivers/char/tty_io.c,
tty_open() that is unhappy about seeing the tty line discipline go away
during the tty hangup. See for example

and the reason is that we do the tty_ldisc_halt() outside the
ldisc_mutex in order to be able to flush the scheduled work without a
deadlock with vhangup_work.

However, it turns out that we can solve this particular case by

 - using "cancel_delayed_work_sync()" in tty_ldisc_halt(), which waits
   for just the particular work, rather than synchronizing with any
   random outstanding pending work.

   This won't deadlock, since the we synchronize with doesn't
   care about the ldisc_mutex, it just flushes the tty ldisc buffers.

 - realize that for this particular case, we don't need to wait for any
   hangup work, because we are inside the hangup codepaths ourselves.

so as a result we can just drop the flush_scheduled_work() entirely, and
then move the tty_ldisc_halt() call to inside the mutex.  That way we
never expose the partially torn down ldisc state to tty_open(), and hold
the ldisc_mutex over the whole sequence.
Reported-by: default avatarIngo Molnar <>
Reported-by: default avatarHeinz Diehl <>
Signed-off-by: default avatarLinus Torvalds <>
parent f0a221ef
......@@ -518,7 +518,7 @@ static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
static int tty_ldisc_halt(struct tty_struct *tty)
clear_bit(TTY_LDISC, &tty->flags);
return cancel_delayed_work(&tty->;
return cancel_delayed_work_sync(&tty->;
......@@ -756,12 +756,9 @@ void tty_ldisc_hangup(struct tty_struct *tty)
* N_TTY.
if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) {
/* Make sure the old ldisc is quiescent */
/* Avoid racing set_ldisc or tty_ldisc_release */
if (tty->ldisc) { /* Not yet closed */
/* Switch back to N_TTY */
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment