To: linux-m68k@phil.uni-sb.de
Subject: L68K: ["Theodore Y. Ts'o" <tytso@MIT.EDU>] Re: BUG? tty_flip.h
From: Jes Degn Soerensen <jds@kom.auc.dk>
Date: 10 Sep 1997 11:43:49 +0200
Sender: owner-linux-m68k@phil.uni-sb.de
Reply-To: linux-m68k@phil.uni-sb.de

Hi

Dunno if this might be related to the serial problems we are having,
but it might be worth a try.

Jes
------- Start of forwarded message -------
Date: 	Tue, 9 Sep 1997 21:46:41 -0400
Message-Id: <199709100146.VAA23519@dcl.MIT.EDU>
From: "Theodore Y. Ts'o" <tytso@MIT.EDU>
To: "Andrew E. Mileski" <aem@netcom.ca>, torvalds@transmeta.com
Cc: linux-kernel@vger.rutgers.edu
Subject: Re: BUG? tty_flip.h

   From: "Andrew E. Mileski" <aem@netcom.ca>
   Date: 	Mon, 8 Sep 1997 19:26:46 -0400 (EDT)

   >From linux-2.1.51/include/linux/tty_flip.h

   _INLINE_ void tty_insert_flip_char(struct tty_struct *tty,
				      unsigned char ch, char flag)
   {
	   if (tty->flip.count++ >= TTY_FLIPBUF_SIZE)
		   return;

   The count gets incremented even after the queue is full.
   This wouldn't be a problem if the count wasn't also used
   to empty the queue...but I'm not yet well versed enough
   on the related code to determine if this is the case or not.

Yup, this is a bug.  The following patch should really make it into the
2.0 release; I suspect this may actually be responsible for some really
rare (and mysterious bugs); basically, if you have a system where
interrupts get delayed often, and you're running at very high serial
speeds, you could potentially overwrite some wait queues in the tty
driver structure.  

I'll be including in a set of tty changes for 2.1 fixes as well.
(Although Linus, if you want to simply apply this patch to the 2.1 tree,
feel free.)

						- Ted
	

*** tty_flip.h  1997/09/10 01:39:34     1.1
--- tty_flip.h  1997/09/10 01:39:48
***************
*** 10,17 ****
  _INLINE_ void tty_insert_flip_char(struct tty_struct *tty,
                                   unsigned char ch, char flag)
  {
!       if (tty->flip.count++ >= TTY_FLIPBUF_SIZE)
                return;
        *tty->flip.flag_buf_ptr++ = flag;
        *tty->flip.char_buf_ptr++ = ch;
  }
--- 10,19 ----
  _INLINE_ void tty_insert_flip_char(struct tty_struct *tty,
                                   unsigned char ch, char flag)
  {
!       if (tty->flip.count++ >= TTY_FLIPBUF_SIZE) {
!               tty->flip.count = TTY_FLIPBUF_SIZE;
                return;
+       }
        *tty->flip.flag_buf_ptr++ = flag;
        *tty->flip.char_buf_ptr++ = ch;
  }

------- End of forwarded message -------
