aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/tty_ldisc.c
diff options
context:
space:
mode:
authorJiri Slaby <jslaby@suse.cz>2011-11-16 10:27:07 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2011-11-17 14:36:11 -0500
commitdf92d0561de364de53c42abc5d43e04ab6f326a5 (patch)
tree619d22a1115944133a83070ac6b7bddca3047829 /drivers/tty/tty_ldisc.c
parent6edf0c9b1c26d047370cf2f35ff6bb3082243ec3 (diff)
TTY: ldisc, allow waiting for ldisc arbitrarily long
To fix a nasty bug in ldisc hup vs. reinit we need to wait infinitely long for ldisc to be gone. So here we add a parameter to tty_ldisc_wait_idle to allow that. This is only a preparation for the real fix which is done in the following patches. Signed-off-by: Jiri Slaby <jslaby@suse.cz> Cc: Dave Young <hidave.darkstar@gmail.com> Cc: Dave Jones <davej@redhat.com> Cc: Ben Hutchings <ben@decadent.org.uk> Cc: Dmitriy Matrosov <sgf.dma@gmail.com> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Cc: stable <stable@vger.kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/tty/tty_ldisc.c')
-rw-r--r--drivers/tty/tty_ldisc.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c
index 512c49f98e8..534d176a78e 100644
--- a/drivers/tty/tty_ldisc.c
+++ b/drivers/tty/tty_ldisc.c
@@ -547,15 +547,16 @@ static void tty_ldisc_flush_works(struct tty_struct *tty)
547/** 547/**
548 * tty_ldisc_wait_idle - wait for the ldisc to become idle 548 * tty_ldisc_wait_idle - wait for the ldisc to become idle
549 * @tty: tty to wait for 549 * @tty: tty to wait for
550 * @timeout: for how long to wait at most
550 * 551 *
551 * Wait for the line discipline to become idle. The discipline must 552 * Wait for the line discipline to become idle. The discipline must
552 * have been halted for this to guarantee it remains idle. 553 * have been halted for this to guarantee it remains idle.
553 */ 554 */
554static int tty_ldisc_wait_idle(struct tty_struct *tty) 555static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout)
555{ 556{
556 int ret; 557 long ret;
557 ret = wait_event_timeout(tty_ldisc_idle, 558 ret = wait_event_timeout(tty_ldisc_idle,
558 atomic_read(&tty->ldisc->users) == 1, 5 * HZ); 559 atomic_read(&tty->ldisc->users) == 1, timeout);
559 if (ret < 0) 560 if (ret < 0)
560 return ret; 561 return ret;
561 return ret > 0 ? 0 : -EBUSY; 562 return ret > 0 ? 0 : -EBUSY;
@@ -665,7 +666,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
665 666
666 tty_ldisc_flush_works(tty); 667 tty_ldisc_flush_works(tty);
667 668
668 retval = tty_ldisc_wait_idle(tty); 669 retval = tty_ldisc_wait_idle(tty, 5 * HZ);
669 670
670 tty_lock(); 671 tty_lock();
671 mutex_lock(&tty->ldisc_mutex); 672 mutex_lock(&tty->ldisc_mutex);
@@ -762,7 +763,7 @@ static int tty_ldisc_reinit(struct tty_struct *tty, int ldisc)
762 if (IS_ERR(ld)) 763 if (IS_ERR(ld))
763 return -1; 764 return -1;
764 765
765 WARN_ON_ONCE(tty_ldisc_wait_idle(tty)); 766 WARN_ON_ONCE(tty_ldisc_wait_idle(tty, 5 * HZ));
766 767
767 tty_ldisc_close(tty, tty->ldisc); 768 tty_ldisc_close(tty, tty->ldisc);
768 tty_ldisc_put(tty->ldisc); 769 tty_ldisc_put(tty->ldisc);