>From 6f778e80388f8b1ad65f0c8bfbc874704d77b3eb Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 2 Dec 2011 09:19:05 +0100 Subject: [PATCH 1/1] TTY: ldisc, don't wait with ldisc_mutex Signed-off-by: Jiri Slaby --- drivers/tty/tty_ldisc.c | 16 +++++++++++++--- 1 files changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 24b95db..c93e113 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -527,6 +527,14 @@ static void tty_ldisc_flush_works(struct tty_struct *tty) flush_work_sync(&tty->buf.work); } +static bool tty_ldisc_is_idle(struct tty_struct *tty) +{ + bool idle; + mutex_lock(&tty->ldisc_mutex); + idle = !tty->ldisc || atomic_read(&tty->ldisc->users) == 1; + mutex_unlock(&tty->ldisc_mutex); + return idle; +} /** * tty_ldisc_wait_idle - wait for the ldisc to become idle * @tty: tty to wait for @@ -534,12 +542,14 @@ static void tty_ldisc_flush_works(struct tty_struct *tty) * * Wait for the line discipline to become idle. The discipline must * have been halted for this to guarantee it remains idle. + * + * Locking: neither BTM, nor tty->ldisc_mutex must be held */ static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout) { long ret; - ret = wait_event_timeout(tty_ldisc_idle, - atomic_read(&tty->ldisc->users) == 1, timeout); + ret = wait_event_timeout(tty_ldisc_idle, tty_ldisc_is_idle(tty), + timeout); return ret > 0 ? 0 : -EBUSY; } @@ -830,6 +840,7 @@ retry: if (atomic_read(&tty->ldisc->users) != 1) { char cur_n[TASK_COMM_LEN], tty_n[64]; long timeout = 3 * HZ; + mutex_unlock(&tty->ldisc_mutex); tty_unlock(); while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) { @@ -839,7 +850,6 @@ retry: __func__, get_task_comm(cur_n, current), tty_name(tty, tty_n)); } - mutex_unlock(&tty->ldisc_mutex); goto retry; } -- 1.7.7.3