| From 37b164578826406a173ca7c20d9ba7430134d23e Mon Sep 17 00:00:00 2001 |
| From: Peter Hurley <peter@hurleysoftware.com> |
| Date: Thu, 16 Oct 2014 13:51:30 -0400 |
| Subject: tty: Fix high cpu load if tty is unreleaseable |
| |
| From: Peter Hurley <peter@hurleysoftware.com> |
| |
| commit 37b164578826406a173ca7c20d9ba7430134d23e upstream. |
| |
| Kernel oops can cause the tty to be unreleaseable (for example, if |
| n_tty_read() crashes while on the read_wait queue). This will cause |
| tty_release() to endlessly loop without sleeping. |
| |
| Use a killable sleep timeout which grows by 2n+1 jiffies over the interval |
| [0, 120 secs.) and then jumps to forever (but still killable). |
| |
| NB: killable just allows for the task to be rewoken manually, not |
| to be terminated. |
| |
| Signed-off-by: Peter Hurley <peter@hurleysoftware.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/tty/tty_io.c | 7 ++++++- |
| 1 file changed, 6 insertions(+), 1 deletion(-) |
| |
| --- a/drivers/tty/tty_io.c |
| +++ b/drivers/tty/tty_io.c |
| @@ -1686,6 +1686,7 @@ int tty_release(struct inode *inode, str |
| int pty_master, tty_closing, o_tty_closing, do_sleep; |
| int idx; |
| char buf[64]; |
| + long timeout = 0; |
| |
| if (tty_paranoia_check(tty, inode, __func__)) |
| return 0; |
| @@ -1770,7 +1771,11 @@ int tty_release(struct inode *inode, str |
| __func__, tty_name(tty, buf)); |
| tty_unlock_pair(tty, o_tty); |
| mutex_unlock(&tty_mutex); |
| - schedule(); |
| + schedule_timeout_killable(timeout); |
| + if (timeout < 120 * HZ) |
| + timeout = 2 * timeout + 1; |
| + else |
| + timeout = MAX_SCHEDULE_TIMEOUT; |
| } |
| |
| /* |