diff options
author | Jiri Slaby <jslaby@suse.cz> | 2011-11-16 10:27:07 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-11-17 14:36:11 -0500 |
commit | df92d0561de364de53c42abc5d43e04ab6f326a5 (patch) | |
tree | 619d22a1115944133a83070ac6b7bddca3047829 /drivers/tty/tty_ldisc.c | |
parent | 6edf0c9b1c26d047370cf2f35ff6bb3082243ec3 (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.c | 11 |
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 | */ |
554 | static int tty_ldisc_wait_idle(struct tty_struct *tty) | 555 | static 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); |