diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-04-28 00:36:39 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-04-28 00:36:39 -0400 |
commit | d35cc56ddfc948d8df1aa6d41ac345fcec01854d (patch) | |
tree | 7e23a0e3dde639236e019aa88309d919941958e5 /drivers/tty/tty_buffer.c | |
parent | 86d56134f1b67d0c18025ba5cade95c048ed528d (diff) | |
parent | d1db0eea852497762cab43b905b879dfcd3b8987 (diff) |
Merge 3.15-rc3 into staging-next
Diffstat (limited to 'drivers/tty/tty_buffer.c')
-rw-r--r-- | drivers/tty/tty_buffer.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 8ebd9f88a6f6..f1d30f6945af 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c | |||
@@ -255,11 +255,16 @@ static int __tty_buffer_request_room(struct tty_port *port, size_t size, | |||
255 | if (change || left < size) { | 255 | if (change || left < size) { |
256 | /* This is the slow path - looking for new buffers to use */ | 256 | /* This is the slow path - looking for new buffers to use */ |
257 | if ((n = tty_buffer_alloc(port, size)) != NULL) { | 257 | if ((n = tty_buffer_alloc(port, size)) != NULL) { |
258 | unsigned long iflags; | ||
259 | |||
258 | n->flags = flags; | 260 | n->flags = flags; |
259 | buf->tail = n; | 261 | buf->tail = n; |
262 | |||
263 | spin_lock_irqsave(&buf->flush_lock, iflags); | ||
260 | b->commit = b->used; | 264 | b->commit = b->used; |
261 | smp_mb(); | ||
262 | b->next = n; | 265 | b->next = n; |
266 | spin_unlock_irqrestore(&buf->flush_lock, iflags); | ||
267 | |||
263 | } else if (change) | 268 | } else if (change) |
264 | size = 0; | 269 | size = 0; |
265 | else | 270 | else |
@@ -443,6 +448,7 @@ static void flush_to_ldisc(struct work_struct *work) | |||
443 | mutex_lock(&buf->lock); | 448 | mutex_lock(&buf->lock); |
444 | 449 | ||
445 | while (1) { | 450 | while (1) { |
451 | unsigned long flags; | ||
446 | struct tty_buffer *head = buf->head; | 452 | struct tty_buffer *head = buf->head; |
447 | int count; | 453 | int count; |
448 | 454 | ||
@@ -450,14 +456,19 @@ static void flush_to_ldisc(struct work_struct *work) | |||
450 | if (atomic_read(&buf->priority)) | 456 | if (atomic_read(&buf->priority)) |
451 | break; | 457 | break; |
452 | 458 | ||
459 | spin_lock_irqsave(&buf->flush_lock, flags); | ||
453 | count = head->commit - head->read; | 460 | count = head->commit - head->read; |
454 | if (!count) { | 461 | if (!count) { |
455 | if (head->next == NULL) | 462 | if (head->next == NULL) { |
463 | spin_unlock_irqrestore(&buf->flush_lock, flags); | ||
456 | break; | 464 | break; |
465 | } | ||
457 | buf->head = head->next; | 466 | buf->head = head->next; |
467 | spin_unlock_irqrestore(&buf->flush_lock, flags); | ||
458 | tty_buffer_free(port, head); | 468 | tty_buffer_free(port, head); |
459 | continue; | 469 | continue; |
460 | } | 470 | } |
471 | spin_unlock_irqrestore(&buf->flush_lock, flags); | ||
461 | 472 | ||
462 | count = receive_buf(tty, head, count); | 473 | count = receive_buf(tty, head, count); |
463 | if (!count) | 474 | if (!count) |
@@ -512,6 +523,7 @@ void tty_buffer_init(struct tty_port *port) | |||
512 | struct tty_bufhead *buf = &port->buf; | 523 | struct tty_bufhead *buf = &port->buf; |
513 | 524 | ||
514 | mutex_init(&buf->lock); | 525 | mutex_init(&buf->lock); |
526 | spin_lock_init(&buf->flush_lock); | ||
515 | tty_buffer_reset(&buf->sentinel, 0); | 527 | tty_buffer_reset(&buf->sentinel, 0); |
516 | buf->head = &buf->sentinel; | 528 | buf->head = &buf->sentinel; |
517 | buf->tail = &buf->sentinel; | 529 | buf->tail = &buf->sentinel; |