Skip to content

Commit 3669752

Browse files
peterhurleygregkh
authored andcommitted
tty: Replace ldisc locking with ldisc_sem
Line discipline locking was performed with a combination of a mutex, a status bit, a count, and a waitqueue -- basically, a rw semaphore. Replace the existing combination with an ld_semaphore. Fixes: 1) the 'reference acquire after ldisc locked' bug 2) the over-complicated halt mechanism 3) lock order wrt. tty_lock() 4) dropping locks while changing ldisc 5) previously unidentified deadlock while locking ldisc from both linked ttys concurrently 6) previously unidentified recursive deadlocks Adds much-needed lockdep diagnostics. Signed-off-by: Peter Hurley <peter@hurleysoftware.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent d2c4389 commit 3669752

File tree

5 files changed

+52
-293
lines changed

5 files changed

+52
-293
lines changed

drivers/tty/tty_buffer.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ static void flush_to_ldisc(struct work_struct *work)
429429
return;
430430

431431
disc = tty_ldisc_ref(tty);
432-
if (disc == NULL) /* !TTY_LDISC */
432+
if (disc == NULL)
433433
return;
434434

435435
spin_lock_irqsave(&buf->lock, flags);

drivers/tty/tty_io.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1388,8 +1388,7 @@ static int tty_reopen(struct tty_struct *tty)
13881388
struct tty_driver *driver = tty->driver;
13891389

13901390
if (test_bit(TTY_CLOSING, &tty->flags) ||
1391-
test_bit(TTY_HUPPING, &tty->flags) ||
1392-
test_bit(TTY_LDISC_CHANGING, &tty->flags))
1391+
test_bit(TTY_HUPPING, &tty->flags))
13931392
return -EIO;
13941393

13951394
if (driver->type == TTY_DRIVER_TYPE_PTY &&
@@ -1405,7 +1404,7 @@ static int tty_reopen(struct tty_struct *tty)
14051404
}
14061405
tty->count++;
14071406

1408-
WARN_ON(!test_bit(TTY_LDISC, &tty->flags));
1407+
WARN_ON(!tty->ldisc);
14091408

14101409
return 0;
14111410
}
@@ -3017,7 +3016,7 @@ void initialize_tty_struct(struct tty_struct *tty,
30173016
tty->pgrp = NULL;
30183017
mutex_init(&tty->legacy_mutex);
30193018
mutex_init(&tty->termios_mutex);
3020-
mutex_init(&tty->ldisc_mutex);
3019+
init_ldsem(&tty->ldisc_sem);
30213020
init_waitqueue_head(&tty->write_wait);
30223021
init_waitqueue_head(&tty->read_wait);
30233022
INIT_WORK(&tty->hangup_work, do_tty_hangup);

0 commit comments

Comments
 (0)