[Devel] [PATCH RHEL7 COMMIT] tty: Fix task hang if one of peers is sitting in read
Konstantin Khorenko
khorenko at virtuozzo.com
Thu Jan 28 11:02:43 PST 2016
The commit is pushed to "branch-rh7-3.10.0-327.3.1-vz7.10.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-327.3.1.vz7.10.7
------>
commit d7a8b04ecac8408598a9b3aa4aa0f4957796bdde
Author: Cyrill Gorcunov <gorcunov at virtuozzo.com>
Date: Thu Jan 28 23:02:43 2016 +0400
tty: Fix task hang if one of peers is sitting in read
The locking scheme has been reworked significantly on current
vanilla kernel, so here is a minimal patch which eliminate
task hanging waiting for tty lock.
We've noticed this issue during our vtty console testing:
when we're entering into console the container spawns
"login" which calls vhangup and close all fds immediately,
so the "vzctl console" code continue hanging inside loop
| vzctl waiting for password:
|
| [root at pcs7 ~]# cat /proc/2482/stack
| [<ffffffff814b1935>] n_tty_read+0x336/0x721
| [<ffffffff814accb4>] tty_read+0x89/0xcb
| [<ffffffff81183651>] vfs_read+0xaf/0xf3
| [<ffffffff81183d5f>] SyS_read+0x50/0x79
| [<ffffffff817991b2>] system_call_fastpath+0x16/0x1b
| [<ffffffffffffffff>] 0xffffffffffffffff
|
| login calls for vhangup
|
| [root at pcs7 ~]# cat /proc/2314/stack
| [<ffffffff814b51ae>] __ldsem_down_write_nested+0xf7/0x1c6
| [<ffffffff814b54cd>] ldsem_down_write_nested+0x38/0x3f
| [<ffffffff814b37a4>] tty_ldisc_hangup+0xd1/0x1b9
| [<ffffffff814aca10>] __tty_hangup+0x2d3/0x3a3
| [<ffffffff814acaf0>] tty_vhangup+0x10/0x12
| [<ffffffff814acd15>] tty_vhangup_self+0x1f/0x2a
| [<ffffffff81182cf4>] sys_vhangup+0x20/0x27
| [<ffffffff817991b2>] system_call_fastpath+0x16/0x1b
| [<ffffffffffffffff>] 0xffffffffffffffff
The primary commit in vanilla kernel which address this
| commit fae76e9adfa450f4c2dd5773265eb3c811a9c484
| Author: Peter Hurley <peter at hurleysoftware.com>
| Date: Wed Nov 5 12:13:07 2014 -0500
|
| tty: Fix hung task on pty hangup
Ufortunately it's not suitable to cherry-picking
because of related changes done in tty layer. So
I made kind of minimal fix which treats the issue
- drop tty_ldisc_lock_pair and tty_unlock/tty_lock
calls from tty_ldisc_hangup: sole locking of
@ldisc_sem should be safe
- same with tty_ldisc_release: no need for
tty_lock_pair, plain @ldisc_sem taken on
both ends with tty_ldisc_lock_pair help
should order locking.
The tests in the bug are passed and "console"
action works as expected but better continue
wathing over tty layer.
https://jira.sw.ru/browse/PSBM-43454
Signed-off-by: Cyrill Gorcunov <gorcunov at virtuozzo.com>
CC: Vladimir Davydov <vdavydov at virtuozzo.com>
CC: Konstantin Khorenko <khorenko at virtuozzo.com>
---
drivers/tty/tty_ldisc.c | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c
index b7b8048..d389c82 100644
--- a/drivers/tty/tty_ldisc.c
+++ b/drivers/tty/tty_ldisc.c
@@ -679,16 +679,13 @@ void tty_ldisc_hangup(struct tty_struct *tty)
wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
wake_up_interruptible_poll(&tty->read_wait, POLLIN);
- tty_unlock(tty);
-
/*
* Shutdown the current line discipline, and reset it to
* N_TTY if need be.
*
* Avoid racing set_ldisc or tty_ldisc_release
*/
- tty_ldisc_lock_pair(tty, tty->link);
- tty_lock(tty);
+ tty_ldisc_lock(tty, MAX_SCHEDULE_TIMEOUT);
if (tty->ldisc) {
@@ -710,7 +707,7 @@ void tty_ldisc_hangup(struct tty_struct *tty)
WARN_ON(tty_ldisc_open(tty, tty->ldisc));
}
}
- tty_ldisc_enable_pair(tty, tty->link);
+ tty_ldisc_unlock(tty);
if (reset)
tty_reset_termios(tty);
@@ -780,13 +777,11 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty)
tty_ldisc_debug(tty, "closing ldisc: %p\n", tty->ldisc);
tty_ldisc_lock_pair(tty, o_tty);
- tty_lock_pair(tty, o_tty);
tty_ldisc_kill(tty);
if (o_tty)
tty_ldisc_kill(o_tty);
- tty_unlock_pair(tty, o_tty);
tty_ldisc_unlock_pair(tty, o_tty);
/* And the memory resources remaining (buffers, termios) will be
More information about the Devel
mailing list