aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/tty_io.c
diff options
context:
space:
mode:
authorPeter Hurley <peter@hurleysoftware.com>2013-06-15 07:04:48 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-07-23 19:38:34 -0400
commit36697529b5bbe36911e39a6309e7a7c9250d280a (patch)
tree5cbffa976994cb798e00d60eccb46c6cafc369a1 /drivers/tty/tty_io.c
parentd2c438905f9f718b3d9f5d89ce163fc22bd33995 (diff)
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>
Diffstat (limited to 'drivers/tty/tty_io.c')
-rw-r--r--drivers/tty/tty_io.c7
1 files changed, 3 insertions, 4 deletions
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index fa80af3656a3..0fa5db4c7a7a 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -1388,8 +1388,7 @@ static int tty_reopen(struct tty_struct *tty)
1388 struct tty_driver *driver = tty->driver; 1388 struct tty_driver *driver = tty->driver;
1389 1389
1390 if (test_bit(TTY_CLOSING, &tty->flags) || 1390 if (test_bit(TTY_CLOSING, &tty->flags) ||
1391 test_bit(TTY_HUPPING, &tty->flags) || 1391 test_bit(TTY_HUPPING, &tty->flags))
1392 test_bit(TTY_LDISC_CHANGING, &tty->flags))
1393 return -EIO; 1392 return -EIO;
1394 1393
1395 if (driver->type == TTY_DRIVER_TYPE_PTY && 1394 if (driver->type == TTY_DRIVER_TYPE_PTY &&
@@ -1405,7 +1404,7 @@ static int tty_reopen(struct tty_struct *tty)
1405 } 1404 }
1406 tty->count++; 1405 tty->count++;
1407 1406
1408 WARN_ON(!test_bit(TTY_LDISC, &tty->flags)); 1407 WARN_ON(!tty->ldisc);
1409 1408
1410 return 0; 1409 return 0;
1411} 1410}
@@ -3017,7 +3016,7 @@ void initialize_tty_struct(struct tty_struct *tty,
3017 tty->pgrp = NULL; 3016 tty->pgrp = NULL;
3018 mutex_init(&tty->legacy_mutex); 3017 mutex_init(&tty->legacy_mutex);
3019 mutex_init(&tty->termios_mutex); 3018 mutex_init(&tty->termios_mutex);
3020 mutex_init(&tty->ldisc_mutex); 3019 init_ldsem(&tty->ldisc_sem);
3021 init_waitqueue_head(&tty->write_wait); 3020 init_waitqueue_head(&tty->write_wait);
3022 init_waitqueue_head(&tty->read_wait); 3021 init_waitqueue_head(&tty->read_wait);
3023 INIT_WORK(&tty->hangup_work, do_tty_hangup); 3022 INIT_WORK(&tty->hangup_work, do_tty_hangup);