Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 364252
b: refs/heads/master
c: 168942c
h: refs/heads/master
v: v3
  • Loading branch information
Peter Hurley authored and Greg Kroah-Hartman committed Mar 18, 2013
1 parent e1a4697 commit f4150ca
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 19 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 79901317ce80c43a0249ccc6e3fea9d0968e159e
refs/heads/master: 168942c9fa01916173a7b72ac67e1d218d571013
54 changes: 36 additions & 18 deletions trunk/drivers/tty/tty_ldisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,41 @@ static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout)
return ret > 0 ? 0 : -EBUSY;
}

/**
* tty_ldisc_hangup_wait_idle - wait for the ldisc to become idle
* @tty: tty to wait for
*
* Wait for the line discipline to become idle. The discipline must
* have been halted for this to guarantee it remains idle.
*
* Caller must hold legacy and ->ldisc_mutex.
*/
static bool tty_ldisc_hangup_wait_idle(struct tty_struct *tty)
{
while (tty->ldisc) { /* Not yet closed */
if (atomic_read(&tty->ldisc->users) != 1) {
char cur_n[TASK_COMM_LEN], tty_n[64];
long timeout = 3 * HZ;
tty_unlock(tty);

while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) {
timeout = MAX_SCHEDULE_TIMEOUT;
printk_ratelimited(KERN_WARNING
"%s: waiting (%s) for %s took too long, but we keep waiting...\n",
__func__, get_task_comm(cur_n, current),
tty_name(tty, tty_n));
}
/* must reacquire both locks and preserve lock order */
mutex_unlock(&tty->ldisc_mutex);
tty_lock(tty);
mutex_lock(&tty->ldisc_mutex);
continue;
}
break;
}
return !!tty->ldisc;
}

/**
* tty_set_ldisc - set line discipline
* @tty: the terminal to set
Expand Down Expand Up @@ -826,31 +861,14 @@ void tty_ldisc_hangup(struct tty_struct *tty)
cancel_work_sync(&tty->port->buf.work);
set_bit(TTY_LDISC_HALTED, &tty->flags);
mutex_unlock(&tty->ldisc_mutex);
retry:
tty_lock(tty);
mutex_lock(&tty->ldisc_mutex);

/* At this point we have a closed ldisc and we want to
reopen it. We could defer this to the next open but
it means auditing a lot of other paths so this is
a FIXME */
if (tty->ldisc) { /* Not yet closed */
if (atomic_read(&tty->ldisc->users) != 1) {
char cur_n[TASK_COMM_LEN], tty_n[64];
long timeout = 3 * HZ;
tty_unlock(tty);

while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) {
timeout = MAX_SCHEDULE_TIMEOUT;
printk_ratelimited(KERN_WARNING
"%s: waiting (%s) for %s took too long, but we keep waiting...\n",
__func__, get_task_comm(cur_n, current),
tty_name(tty, tty_n));
}
mutex_unlock(&tty->ldisc_mutex);
goto retry;
}

if (tty_ldisc_hangup_wait_idle(tty)) {
if (reset == 0) {

if (!tty_ldisc_reinit(tty, tty->termios.c_line))
Expand Down

0 comments on commit f4150ca

Please sign in to comment.