Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 168942c9 authored by Peter Hurley's avatar Peter Hurley Committed by Greg Kroah-Hartman
Browse files

tty: Refactor wait for ldisc refs out of tty_ldisc_hangup()



Refactor tty_ldisc_hangup() to extract standalone function,
tty_ldisc_hangup_wait_idle(), to wait for ldisc references
to be released.

Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 79901317
Loading
Loading
Loading
Loading
+36 −18
Original line number Diff line number Diff line
@@ -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
@@ -826,7 +861,6 @@ 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);

@@ -834,23 +868,7 @@ retry:
	   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))