From 9d0d1f832451c283fb93d3300531ae7b8f7b3c37 Mon Sep 17 00:00:00 2001 From: Paul Fulghum Date: Sun, 27 Aug 2006 03:36:58 +0200 Subject: [PATCH] tty serialize flush_to_ldisc 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 Acked-by: Alan Cox Signed-off-by: Adrian Bunk --- drivers/char/tty_io.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index edaee70b2e66..34d31263d330 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -2759,7 +2759,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; @@ -2776,7 +2776,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; @@ -2785,10 +2787,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); } -- 2.39.5