diff options
author | Ingo Molnar <mingo@elte.hu> | 2011-06-16 15:23:15 +0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2011-06-16 15:23:22 +0400 |
commit | b4f9f2b64aa189c5584f266f4f0343af7a705441 (patch) | |
tree | f410718bb93590ff61682b566c10f70d5883bbcd /drivers/tty/tty_buffer.c | |
parent | 76369139ceb955deefc509e6e12ce9d6ce50ccab (diff) | |
parent | 2c53b436a30867eb6b47dd7bab23ba638d1fb0d2 (diff) | |
download | linux-b4f9f2b64aa189c5584f266f4f0343af7a705441.tar.xz |
Merge commit 'v3.0-rc3' into perf/core
Merge reason: add the latest fixes.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/tty/tty_buffer.c')
-rw-r--r-- | drivers/tty/tty_buffer.c | 27 |
1 files changed, 7 insertions, 20 deletions
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 46de2e075dac..6c9b7cd6778a 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -413,10 +413,8 @@ static void flush_to_ldisc(struct work_struct *work) spin_lock_irqsave(&tty->buf.lock, flags); if (!test_and_set_bit(TTY_FLUSHING, &tty->flags)) { - struct tty_buffer *head, *tail = tty->buf.tail; - int seen_tail = 0; + struct tty_buffer *head; while ((head = tty->buf.head) != NULL) { - int copied; int count; char *char_buf; unsigned char *flag_buf; @@ -425,15 +423,6 @@ static void flush_to_ldisc(struct work_struct *work) if (!count) { if (head->next == NULL) break; - /* - There's a possibility tty might get new buffer - added during the unlock window below. We could - end up spinning in here forever hogging the CPU - completely. To avoid this let's have a rest each - time we processed the tail buffer. - */ - if (tail == head) - seen_tail = 1; tty->buf.head = head->next; tty_buffer_free(tty, head); continue; @@ -443,19 +432,17 @@ static void flush_to_ldisc(struct work_struct *work) line discipline as we want to empty the queue */ if (test_bit(TTY_FLUSHPENDING, &tty->flags)) break; + if (!tty->receive_room) + break; + if (count > tty->receive_room) + count = tty->receive_room; char_buf = head->char_buf_ptr + head->read; flag_buf = head->flag_buf_ptr + head->read; + head->read += count; spin_unlock_irqrestore(&tty->buf.lock, flags); - copied = disc->ops->receive_buf(tty, char_buf, + disc->ops->receive_buf(tty, char_buf, flag_buf, count); spin_lock_irqsave(&tty->buf.lock, flags); - - head->read += copied; - - if (copied == 0 || seen_tail) { - schedule_work(&tty->buf.work); - break; - } } clear_bit(TTY_FLUSHING, &tty->flags); } |