aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorJiri Slaby <jslaby@suse.cz>2011-11-16 10:27:07 -0500
committerHerton Ronaldo Krzesinski <herton.krzesinski@canonical.com>2011-12-12 08:06:57 -0500
commitb8921a9c4401a830a10b73966189d50627bb9f17 (patch)
tree72aa8498ce4dd51f97ff7425a327a98e82d3bb4a /drivers/tty
parent4a0eacc9cf3cfbe6141758d3364e6a2f846817cc (diff)
TTY: ldisc, allow waiting for ldisc arbitrarily long
BugLink: http://bugs.launchpad.net/bugs/897514 commit df92d0561de364de53c42abc5d43e04ab6f326a5 upstream. 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> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
Diffstat (limited to 'drivers/tty')
-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 ef925d58171..363d5689a84 100644
--- a/drivers/tty/tty_ldisc.c
+++ b/drivers/tty/tty_ldisc.c
@@ -548,15 +548,16 @@ static void tty_ldisc_flush_works(struct tty_struct *tty)
548/** 548/**
549 * tty_ldisc_wait_idle - wait for the ldisc to become idle 549 * tty_ldisc_wait_idle - wait for the ldisc to become idle
550 * @tty: tty to wait for 550 * @tty: tty to wait for
551 * @timeout: for how long to wait at most
551 * 552 *
552 * Wait for the line discipline to become idle. The discipline must 553 * Wait for the line discipline to become idle. The discipline must
553 * have been halted for this to guarantee it remains idle. 554 * have been halted for this to guarantee it remains idle.
554 */ 555 */
555static int tty_ldisc_wait_idle(struct tty_struct *tty) 556static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout)
556{ 557{
557 int ret; 558 long ret;
558 ret = wait_event_timeout(tty_ldisc_idle, 559 ret = wait_event_timeout(tty_ldisc_idle,
559 atomic_read(&tty->ldisc->users) == 1, 5 * HZ); 560 atomic_read(&tty->ldisc->users) == 1, timeout);
560 if (ret < 0) 561 if (ret < 0)
561 return ret; 562 return ret;
562 return ret > 0 ? 0 : -EBUSY; 563 return ret > 0 ? 0 : -EBUSY;
@@ -666,7 +667,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
666 667
667 tty_ldisc_flush_works(tty); 668 tty_ldisc_flush_works(tty);
668 669
669 retval = tty_ldisc_wait_idle(tty); 670 retval = tty_ldisc_wait_idle(tty, 5 * HZ);
670 671
671 tty_lock(); 672 tty_lock();
672 mutex_lock(&tty->ldisc_mutex); 673 mutex_lock(&tty->ldisc_mutex);
@@ -763,7 +764,7 @@ static int tty_ldisc_reinit(struct tty_struct *tty, int ldisc)
763 if (IS_ERR(ld)) 764 if (IS_ERR(ld))
764 return -1; 765 return -1;
765 766
766 WARN_ON_ONCE(tty_ldisc_wait_idle(tty)); 767 WARN_ON_ONCE(tty_ldisc_wait_idle(tty, 5 * HZ));
767 768
768 tty_ldisc_close(tty, tty->ldisc); 769 tty_ldisc_close(tty, tty->ldisc);
769 tty_ldisc_put(tty->ldisc); 770 tty_ldisc_put(tty->ldisc);