aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/tty/tty_ldisc.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c
index a69a755035b6..8e0924f55446 100644
--- a/drivers/tty/tty_ldisc.c
+++ b/drivers/tty/tty_ldisc.c
@@ -36,6 +36,7 @@
36 36
37#include <linux/kmod.h> 37#include <linux/kmod.h>
38#include <linux/nsproxy.h> 38#include <linux/nsproxy.h>
39#include <linux/ratelimit.h>
39 40
40/* 41/*
41 * This guards the refcounted line discipline lists. The lock 42 * This guards the refcounted line discipline lists. The lock
@@ -837,7 +838,7 @@ void tty_ldisc_hangup(struct tty_struct *tty)
837 tty_unlock(); 838 tty_unlock();
838 cancel_work_sync(&tty->buf.work); 839 cancel_work_sync(&tty->buf.work);
839 mutex_unlock(&tty->ldisc_mutex); 840 mutex_unlock(&tty->ldisc_mutex);
840 841retry:
841 tty_lock(); 842 tty_lock();
842 mutex_lock(&tty->ldisc_mutex); 843 mutex_lock(&tty->ldisc_mutex);
843 844
@@ -846,7 +847,21 @@ void tty_ldisc_hangup(struct tty_struct *tty)
846 it means auditing a lot of other paths so this is 847 it means auditing a lot of other paths so this is
847 a FIXME */ 848 a FIXME */
848 if (tty->ldisc) { /* Not yet closed */ 849 if (tty->ldisc) { /* Not yet closed */
849 WARN_ON_ONCE(tty_ldisc_wait_idle(tty, 5 * HZ)); 850 if (atomic_read(&tty->ldisc->users) != 1) {
851 char cur_n[TASK_COMM_LEN], tty_n[64];
852 long timeout = 3 * HZ;
853 tty_unlock();
854
855 while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) {
856 timeout = MAX_SCHEDULE_TIMEOUT;
857 printk_ratelimited(KERN_WARNING
858 "%s: waiting (%s) for %s took too long, but we keep waiting...\n",
859 __func__, get_task_comm(cur_n, current),
860 tty_name(tty, tty_n));
861 }
862 mutex_unlock(&tty->ldisc_mutex);
863 goto retry;
864 }
850 865
851 if (reset == 0) { 866 if (reset == 0) {
852 867