lkml.org 
[lkml]   [2011]   [Dec]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: [PATCH 2/5] TTY: ldisc, move wait idle to caller
On 12/02/2011 12:01 AM, Tony Luck wrote:
> One of my systems (HP rx2620 - ia64) has started hanging during shutdown.
> Last messages on the serial console are:
>
> Shutting down service (localfs) network . . . . . . . . . done
> Shutting down D-Bus daemon done
> Running /etc/ini
>
> and there it hangs forever in mid word (totally repeatable stops at "ini" every
> time).
>
> git bisect blames:
>
> commit 300420722e0734a4254f3b634e0f82664495d210
> Author: Jiri Slaby <jslaby@suse.cz>
> Date: Wed Nov 16 16:27:08 2011 +0100
>
> TTY: ldisc, move wait idle to caller
>
> [Though the following commit "TTY: ldisc, wait for ldisc infinitely in hangup"
> sounds like it fits the symptoms]
>
> Ideas?

Thanks. What distro and init do you use? Does the attached patch help?

--
js
suse labs
From 6f778e80388f8b1ad65f0c8bfbc874704d77b3eb Mon Sep 17 00:00:00 2001
From: Jiri Slaby <jslaby@suse.cz>
Date: Fri, 2 Dec 2011 09:19:05 +0100
Subject: [PATCH 1/1] TTY: ldisc, don't wait with ldisc_mutex

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
drivers/tty/tty_ldisc.c | 16 +++++++++++++---
1 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c
index 24b95db..c93e113 100644
--- a/drivers/tty/tty_ldisc.c
+++ b/drivers/tty/tty_ldisc.c
@@ -527,6 +527,14 @@ static void tty_ldisc_flush_works(struct tty_struct *tty)
flush_work_sync(&tty->buf.work);
}

+static bool tty_ldisc_is_idle(struct tty_struct *tty)
+{
+ bool idle;
+ mutex_lock(&tty->ldisc_mutex);
+ idle = !tty->ldisc || atomic_read(&tty->ldisc->users) == 1;
+ mutex_unlock(&tty->ldisc_mutex);
+ return idle;
+}
/**
* tty_ldisc_wait_idle - wait for the ldisc to become idle
* @tty: tty to wait for
@@ -534,12 +542,14 @@ static void tty_ldisc_flush_works(struct tty_struct *tty)
*
* Wait for the line discipline to become idle. The discipline must
* have been halted for this to guarantee it remains idle.
+ *
+ * Locking: neither BTM, nor tty->ldisc_mutex must be held
*/
static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout)
{
long ret;
- ret = wait_event_timeout(tty_ldisc_idle,
- atomic_read(&tty->ldisc->users) == 1, timeout);
+ ret = wait_event_timeout(tty_ldisc_idle, tty_ldisc_is_idle(tty),
+ timeout);
return ret > 0 ? 0 : -EBUSY;
}

@@ -830,6 +840,7 @@ retry:
if (atomic_read(&tty->ldisc->users) != 1) {
char cur_n[TASK_COMM_LEN], tty_n[64];
long timeout = 3 * HZ;
+ mutex_unlock(&tty->ldisc_mutex);
tty_unlock();

while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) {
@@ -839,7 +850,6 @@ retry:
__func__, get_task_comm(cur_n, current),
tty_name(tty, tty_n));
}
- mutex_unlock(&tty->ldisc_mutex);
goto retry;
}

--
1.7.7.3
\
 
 \ /
  Last update: 2011-12-02 09:23    [W:0.146 / U:0.052 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site