diff options
author | Wang YanQing <udknight@gmail.com> | 2017-02-22 06:37:08 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-05-20 08:28:41 -0400 |
commit | 89c91ea375816c2a34c4035c7feb40db3f053ae9 (patch) | |
tree | 148fa42b9166cdd8a651bea45b85493d43cab962 /drivers/tty | |
parent | e38a4c3b0b4a3df1abbe7ae9c175eed62286f963 (diff) |
tty: pty: Fix ldisc flush after userspace become aware of the data already
commit 77dae6134440420bac334581a3ccee94cee1c054 upstream.
While using emacs, cat or others' commands in konsole with recent
kernels, I have met many times that CTRL-C freeze konsole. After
konsole freeze I can't type anything, then I have to open a new one,
it is very annoying.
See bug report:
https://bugs.kde.org/show_bug.cgi?id=175283
The platform in that bug report is Solaris, but now the pty in linux
has the same problem or the same behavior as Solaris :)
It has high possibility to trigger the problem follow steps below:
Note: In my test, BigFile is a text file whose size is bigger than 1G
1:open konsole
1:cat BigFile
2:CTRL-C
After some digging, I find out the reason is that commit 1d1d14da12e7
("pty: Fix buffer flush deadlock") changes the behavior of pty_flush_buffer.
Thread A Thread B
-------- --------
1:n_tty_poll return POLLIN
2:CTRL-C trigger pty_flush_buffer
tty_buffer_flush
n_tty_flush_buffer
3:attempt to check count of chars:
ioctl(fd, TIOCINQ, &available)
available is equal to 0
4:read(fd, buffer, avaiable)
return 0
5:konsole close fd
Yes, I know we could use the same patch included in the BUG report as
a workaround for linux platform too. But I think the data in ldisc is
belong to application of another side, we shouldn't clear it when we
want to flush write buffer of this side in pty_flush_buffer. So I think
it is better to disable ldisc flush in pty_flush_buffer, because its new
hehavior bring no benefit except that it mess up the behavior between
POLLIN, and TIOCINQ or FIONREAD.
Also I find no flush_buffer function in others' tty driver has the
same behavior as current pty_flush_buffer.
Fixes: 1d1d14da12e7 ("pty: Fix buffer flush deadlock")
Signed-off-by: Wang YanQing <udknight@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/pty.c | 7 |
1 files changed, 1 insertions, 6 deletions
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index a23fa5ed1d67..2b907385b4a8 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c | |||
@@ -216,16 +216,11 @@ static int pty_signal(struct tty_struct *tty, int sig) | |||
216 | static void pty_flush_buffer(struct tty_struct *tty) | 216 | static void pty_flush_buffer(struct tty_struct *tty) |
217 | { | 217 | { |
218 | struct tty_struct *to = tty->link; | 218 | struct tty_struct *to = tty->link; |
219 | struct tty_ldisc *ld; | ||
220 | 219 | ||
221 | if (!to) | 220 | if (!to) |
222 | return; | 221 | return; |
223 | 222 | ||
224 | ld = tty_ldisc_ref(to); | 223 | tty_buffer_flush(to, NULL); |
225 | tty_buffer_flush(to, ld); | ||
226 | if (ld) | ||
227 | tty_ldisc_deref(ld); | ||
228 | |||
229 | if (to->packet) { | 224 | if (to->packet) { |
230 | spin_lock_irq(&tty->ctrl_lock); | 225 | spin_lock_irq(&tty->ctrl_lock); |
231 | tty->ctrl_status |= TIOCPKT_FLUSHWRITE; | 226 | tty->ctrl_status |= TIOCPKT_FLUSHWRITE; |