diff options
author | Jiri Slaby <jslaby@suse.cz> | 2011-11-16 10:27:07 -0500 |
---|---|---|
committer | Herton Ronaldo Krzesinski <herton.krzesinski@canonical.com> | 2011-12-12 08:06:57 -0500 |
commit | b8921a9c4401a830a10b73966189d50627bb9f17 (patch) | |
tree | 72aa8498ce4dd51f97ff7425a327a98e82d3bb4a /drivers/tty | |
parent | 4a0eacc9cf3cfbe6141758d3364e6a2f846817cc (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.c | 11 |
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 | */ |
555 | static int tty_ldisc_wait_idle(struct tty_struct *tty) | 556 | static 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); |