aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/tty_ldisc.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2011-11-26 23:07:25 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2011-11-26 23:07:25 -0500
commitdd7c7c3f69291baa488b8a50db683d5fbf44166a (patch)
tree925bf294f30dffaa67a983c3859926ff53937e14 /drivers/tty/tty_ldisc.c
parent161e773cbd0c3d1b5b8cc00602e1f72de61ed4f7 (diff)
parentcaca6a03d365883564885f2c1da3e88dcf65d139 (diff)
Merge 3.2-rc3 into tty-next to handle merge conflict in tty_ldisc.c
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/tty/tty_ldisc.c')
-rw-r--r--drivers/tty/tty_ldisc.c30
1 files changed, 23 insertions, 7 deletions
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c
index 174db3b0c09..24b95db75d8 100644
--- a/drivers/tty/tty_ldisc.c
+++ b/drivers/tty/tty_ldisc.c
@@ -18,6 +18,7 @@
18#include <linux/bitops.h> 18#include <linux/bitops.h>
19#include <linux/seq_file.h> 19#include <linux/seq_file.h>
20#include <linux/uaccess.h> 20#include <linux/uaccess.h>
21#include <linux/ratelimit.h>
21 22
22/* 23/*
23 * This guards the refcounted line discipline lists. The lock 24 * This guards the refcounted line discipline lists. The lock
@@ -529,15 +530,16 @@ static void tty_ldisc_flush_works(struct tty_struct *tty)
529/** 530/**
530 * tty_ldisc_wait_idle - wait for the ldisc to become idle 531 * tty_ldisc_wait_idle - wait for the ldisc to become idle
531 * @tty: tty to wait for 532 * @tty: tty to wait for
533 * @timeout: for how long to wait at most
532 * 534 *
533 * Wait for the line discipline to become idle. The discipline must 535 * Wait for the line discipline to become idle. The discipline must
534 * have been halted for this to guarantee it remains idle. 536 * have been halted for this to guarantee it remains idle.
535 */ 537 */
536static int tty_ldisc_wait_idle(struct tty_struct *tty) 538static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout)
537{ 539{
538 int ret; 540 long ret;
539 ret = wait_event_timeout(tty_ldisc_idle, 541 ret = wait_event_timeout(tty_ldisc_idle,
540 atomic_read(&tty->ldisc->users) == 1, 5 * HZ); 542 atomic_read(&tty->ldisc->users) == 1, timeout);
541 return ret > 0 ? 0 : -EBUSY; 543 return ret > 0 ? 0 : -EBUSY;
542} 544}
543 545
@@ -645,7 +647,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
645 647
646 tty_ldisc_flush_works(tty); 648 tty_ldisc_flush_works(tty);
647 649
648 retval = tty_ldisc_wait_idle(tty); 650 retval = tty_ldisc_wait_idle(tty, 5 * HZ);
649 651
650 tty_lock(); 652 tty_lock();
651 mutex_lock(&tty->ldisc_mutex); 653 mutex_lock(&tty->ldisc_mutex);
@@ -742,8 +744,6 @@ static int tty_ldisc_reinit(struct tty_struct *tty, int ldisc)
742 if (IS_ERR(ld)) 744 if (IS_ERR(ld))
743 return -1; 745 return -1;
744 746
745 WARN_ON_ONCE(tty_ldisc_wait_idle(tty));
746
747 tty_ldisc_close(tty, tty->ldisc); 747 tty_ldisc_close(tty, tty->ldisc);
748 tty_ldisc_put(tty->ldisc); 748 tty_ldisc_put(tty->ldisc);
749 tty->ldisc = NULL; 749 tty->ldisc = NULL;
@@ -818,7 +818,7 @@ void tty_ldisc_hangup(struct tty_struct *tty)
818 tty_unlock(); 818 tty_unlock();
819 cancel_work_sync(&tty->buf.work); 819 cancel_work_sync(&tty->buf.work);
820 mutex_unlock(&tty->ldisc_mutex); 820 mutex_unlock(&tty->ldisc_mutex);
821 821retry:
822 tty_lock(); 822 tty_lock();
823 mutex_lock(&tty->ldisc_mutex); 823 mutex_lock(&tty->ldisc_mutex);
824 824
@@ -827,6 +827,22 @@ void tty_ldisc_hangup(struct tty_struct *tty)
827 it means auditing a lot of other paths so this is 827 it means auditing a lot of other paths so this is
828 a FIXME */ 828 a FIXME */
829 if (tty->ldisc) { /* Not yet closed */ 829 if (tty->ldisc) { /* Not yet closed */
830 if (atomic_read(&tty->ldisc->users) != 1) {
831 char cur_n[TASK_COMM_LEN], tty_n[64];
832 long timeout = 3 * HZ;
833 tty_unlock();
834
835 while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) {
836 timeout = MAX_SCHEDULE_TIMEOUT;
837 printk_ratelimited(KERN_WARNING
838 "%s: waiting (%s) for %s took too long, but we keep waiting...\n",
839 __func__, get_task_comm(cur_n, current),
840 tty_name(tty, tty_n));
841 }
842 mutex_unlock(&tty->ldisc_mutex);
843 goto retry;
844 }
845
830 if (reset == 0) { 846 if (reset == 0) {
831 847
832 if (!tty_ldisc_reinit(tty, tty->termios->c_line)) 848 if (!tty_ldisc_reinit(tty, tty->termios->c_line))