]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
add tty patch to queue
authorGreg Kroah-Hartman <gregkh@suse.de>
Thu, 3 Aug 2006 20:45:09 +0000 (13:45 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 3 Aug 2006 20:45:09 +0000 (13:45 -0700)
queue-2.6.17/series
queue-2.6.17/tty-serialize-flush_to_ldisc.patch [new file with mode: 0644]

index 0df4550dddb3d17dcfc9413e6e21fa17ff4aafc1..ef401a4ad16ded8c7cbec35801f1d7fd2097d94f 100644 (file)
@@ -18,3 +18,4 @@ e1000-add-forgotten-pci-id-for-supported-device.patch
 cond_resched-fix.patch
 fix-budget-av-compile-failure.patch
 s390-fix-futex_atomic_cmpxchg_inatomic.patch
+tty-serialize-flush_to_ldisc.patch
diff --git a/queue-2.6.17/tty-serialize-flush_to_ldisc.patch b/queue-2.6.17/tty-serialize-flush_to_ldisc.patch
new file mode 100644 (file)
index 0000000..0be7e45
--- /dev/null
@@ -0,0 +1,63 @@
+From paulkf@microgate.com Wed Jul 26 12:11:54 2006
+Subject: tty serialize flush_to_ldisc
+From: Paul Fulghum <paulkf@microgate.com>
+To: Greg KH <greg@kroah.com>
+Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>,
+        Chuck Ebbert <76306.1226@compuserve.com>,
+        linux-stable <stable@kernel.org>
+Date: Wed, 26 Jul 2006 14:10:29 -0500
+Message-Id: <1153941029.6903.5.camel@amdx2.microgate.com>
+
+From: Paul Fulghum <paulkf@microgate.com>
+
+Serialize processing of tty buffers in flush_to_ldisc
+to fix (very rare) corruption of tty buffer free list
+on SMP systems.
+
+Signed-off-by: Paul Fulghum <paulkf@microgate.com>
+Acked-by: Alan Cox <alan@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/char/tty_io.c |   14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+--- linux-2.6.17.7.orig/drivers/char/tty_io.c
++++ linux-2.6.17.7/drivers/char/tty_io.c
+@@ -2776,7 +2776,7 @@ static void flush_to_ldisc(void *private
+       struct tty_struct *tty = (struct tty_struct *) private_;
+       unsigned long   flags;
+       struct tty_ldisc *disc;
+-      struct tty_buffer *tbuf;
++      struct tty_buffer *tbuf, *head;
+       int count;
+       char *char_buf;
+       unsigned char *flag_buf;
+@@ -2793,7 +2793,9 @@ static void flush_to_ldisc(void *private
+               goto out;
+       }
+       spin_lock_irqsave(&tty->buf.lock, flags);
+-      while((tbuf = tty->buf.head) != NULL) {
++      head = tty->buf.head;
++      tty->buf.head = NULL;
++      while((tbuf = head) != NULL) {
+               while ((count = tbuf->commit - tbuf->read) != 0) {
+                       char_buf = tbuf->char_buf_ptr + tbuf->read;
+                       flag_buf = tbuf->flag_buf_ptr + tbuf->read;
+@@ -2802,10 +2804,12 @@ static void flush_to_ldisc(void *private
+                       disc->receive_buf(tty, char_buf, flag_buf, count);
+                       spin_lock_irqsave(&tty->buf.lock, flags);
+               }
+-              if (tbuf->active)
++              if (tbuf->active) {
++                      tty->buf.head = head;
+                       break;
+-              tty->buf.head = tbuf->next;
+-              if (tty->buf.head == NULL)
++              }
++              head = tbuf->next;
++              if (head == NULL)
+                       tty->buf.tail = NULL;
+               tty_buffer_free(tty, tbuf);
+       }