Commit 202c4675 authored by Linus Torvalds's avatar Linus Torvalds

pty_write: don't do a tty_wakeup() when the buffers are full

Commit ac89a917 ("pty: don't limit the writes to 'pty_space()' inside
'pty_write()'") removed the pty_space() checking, in order to let the
regular tty buffer code limit the buffering itself.

That was all good, but as a subtle side effect it meant that we'd be
doing a tty_wakeup() even in the case where the buffers were all filled
up, and didn't actually make any progress on the write.

Which sounds innocuous, but it interacts very badly with the ppp_async
code, which has an infinite loop in ppp_async_push() that tries to push
out data to the tty.  When we call tty_wakeup(), that loop ends up
thinking that progress was made (see the subtle interactions between
XMIT_WAKEUP and 'tty_stuffed' for details).  End result: one unhappy ppp
user.

Fixed by noticing when tty_insert_flip_string() didn't actually do
anything, and then not doing any more processing (including, very much
not calling tty_wakeup()).
Bisected-and-tested-by: default avatarPeter Volkov <pva@gentoo.org>
Cc: stable@kernel.org (2.6.31)
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent df58bee2
...@@ -120,8 +120,10 @@ static int pty_write(struct tty_struct *tty, const unsigned char *buf, int c) ...@@ -120,8 +120,10 @@ static int pty_write(struct tty_struct *tty, const unsigned char *buf, int c)
/* Stuff the data into the input queue of the other end */ /* Stuff the data into the input queue of the other end */
c = tty_insert_flip_string(to, buf, c); c = tty_insert_flip_string(to, buf, c);
/* And shovel */ /* And shovel */
tty_flip_buffer_push(to); if (c) {
tty_wakeup(tty); tty_flip_buffer_push(to);
tty_wakeup(tty);
}
} }
return c; return c;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment