aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/tty_buffer.c
diff options
context:
space:
mode:
authorPeter Hurley <peter@hurleysoftware.com>2013-06-15 09:36:11 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-07-23 19:47:09 -0400
commitd7a68be4f265be10e24be931c257af30ca55566b (patch)
treec60c359eb4398fae7687320fd2c89220916b9cb9 /drivers/tty/tty_buffer.c
parente9975fdec0138f1b2a85b9624e41660abd9865d4 (diff)
tty: Only perform flip buffer flush from tty_buffer_flush()
Now that dropping the buffer lock is not necessary (as result of converting the spin lock to a mutex), the flip buffer flush no longer needs to be handled by the buffer work. Simply signal a flush is required; the buffer work will exit the i/o loop, which allows tty_buffer_flush() to proceed. Signed-off-by: Peter Hurley <peter@hurleysoftware.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/tty_buffer.c')
-rw-r--r--drivers/tty/tty_buffer.c63
1 files changed, 21 insertions, 42 deletions
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c
index c3c606c52722..39cae611fe59 100644
--- a/drivers/tty/tty_buffer.c
+++ b/drivers/tty/tty_buffer.c
@@ -189,19 +189,11 @@ void tty_buffer_flush(struct tty_struct *tty)
189 struct tty_port *port = tty->port; 189 struct tty_port *port = tty->port;
190 struct tty_bufhead *buf = &port->buf; 190 struct tty_bufhead *buf = &port->buf;
191 191
192 mutex_lock(&buf->flush_mutex); 192 set_bit(TTYP_FLUSHPENDING, &port->iflags);
193 /* If the data is being pushed to the tty layer then we can't
194 process it here. Instead set a flag and the flush_to_ldisc
195 path will process the flush request before it exits */
196 if (test_bit(TTYP_FLUSHING, &port->iflags)) {
197 set_bit(TTYP_FLUSHPENDING, &port->iflags);
198 mutex_unlock(&buf->flush_mutex);
199 wait_event(tty->read_wait,
200 test_bit(TTYP_FLUSHPENDING, &port->iflags) == 0);
201 return;
202 }
203 193
194 mutex_lock(&buf->flush_mutex);
204 __tty_buffer_flush(port); 195 __tty_buffer_flush(port);
196 clear_bit(TTYP_FLUSHPENDING, &port->iflags);
205 mutex_unlock(&buf->flush_mutex); 197 mutex_unlock(&buf->flush_mutex);
206} 198}
207 199
@@ -429,39 +421,26 @@ static void flush_to_ldisc(struct work_struct *work)
429 421
430 mutex_lock(&buf->flush_mutex); 422 mutex_lock(&buf->flush_mutex);
431 423
432 if (!test_and_set_bit(TTYP_FLUSHING, &port->iflags)) { 424 while (1) {
433 while (1) { 425 struct tty_buffer *head = buf->head;
434 struct tty_buffer *head = buf->head; 426 int count;
435 int count; 427
436 428 /* Ldisc or user is trying to flush the buffers. */
437 count = head->commit - head->read; 429 if (test_bit(TTYP_FLUSHPENDING, &port->iflags))
438 if (!count) { 430 break;
439 if (head->next == NULL) 431
440 break; 432 count = head->commit - head->read;
441 buf->head = head->next; 433 if (!count) {
442 tty_buffer_free(port, head); 434 if (head->next == NULL)
443 continue;
444 }
445
446 mutex_unlock(&buf->flush_mutex);
447
448 count = receive_buf(tty, head, count);
449
450 mutex_lock(&buf->flush_mutex);
451
452 /* Ldisc or user is trying to flush the buffers.
453 We may have a deferred request to flush the
454 input buffer, if so pull the chain under the lock
455 and empty the queue */
456 if (test_bit(TTYP_FLUSHPENDING, &port->iflags)) {
457 __tty_buffer_flush(port);
458 clear_bit(TTYP_FLUSHPENDING, &port->iflags);
459 wake_up(&tty->read_wait);
460 break;
461 } else if (!count)
462 break; 435 break;
436 buf->head = head->next;
437 tty_buffer_free(port, head);
438 continue;
463 } 439 }
464 clear_bit(TTYP_FLUSHING, &port->iflags); 440
441 count = receive_buf(tty, head, count);
442 if (!count)
443 break;
465 } 444 }
466 445
467 mutex_unlock(&buf->flush_mutex); 446 mutex_unlock(&buf->flush_mutex);