From: Linus Torvalds <torvalds@osdl.org>

For testing, a patch like this might get rid of the problem by hiding the
race (but for all I know, gcc ends up re-loading it anyway) - you might 
want to check the disassembly. 

However, this patch is just for testing, to verify that your problem 
really is that particular race. It's not a proper fix.

I suspect that pty's should always lock each others line disciplines too, 
not just their "own" side.

Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/drivers/char/pty.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff -puN drivers/char/pty.c~pty-oops-fix drivers/char/pty.c
--- 25/drivers/char/pty.c~pty-oops-fix	Thu Jan 27 16:36:38 2005
+++ 25-akpm/drivers/char/pty.c	Thu Jan 27 16:36:38 2005
@@ -149,13 +149,15 @@ static int pty_write_room(struct tty_str
 static int pty_chars_in_buffer(struct tty_struct *tty)
 {
 	struct tty_struct *to = tty->link;
+	ssize_t (*chars_in_buffer)(struct tty_struct *);
 	int count;
 
-	if (!to || !to->ldisc.chars_in_buffer)
+	/* We should get the line discipline lock for "tty->link" */
+	if (!to || !(chars_in_buffer = to->ldisc.chars_in_buffer))
 		return 0;
 
 	/* The ldisc must report 0 if no characters available to be read */
-	count = to->ldisc.chars_in_buffer(to);
+	count = chars_in_buffer(to);
 
 	if (tty->driver->subtype == PTY_TYPE_SLAVE) return count;
 
_