diff options
author | Peter Hurley <peter@hurleysoftware.com> | 2013-06-15 09:36:11 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-07-23 19:47:09 -0400 |
commit | d7a68be4f265be10e24be931c257af30ca55566b (patch) | |
tree | c60c359eb4398fae7687320fd2c89220916b9cb9 /drivers/tty/tty_buffer.c | |
parent | e9975fdec0138f1b2a85b9624e41660abd9865d4 (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.c | 63 |
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); |