Skip to content

Commit

Permalink
tty: Only perform flip buffer flush from tty_buffer_flush()
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Peter Hurley authored and Greg Kroah-Hartman committed Jul 23, 2013
1 parent e9975fd commit d7a68be
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 43 deletions.
63 changes: 21 additions & 42 deletions drivers/tty/tty_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,19 +189,11 @@ void tty_buffer_flush(struct tty_struct *tty)
struct tty_port *port = tty->port;
struct tty_bufhead *buf = &port->buf;

mutex_lock(&buf->flush_mutex);
/* If the data is being pushed to the tty layer then we can't
process it here. Instead set a flag and the flush_to_ldisc
path will process the flush request before it exits */
if (test_bit(TTYP_FLUSHING, &port->iflags)) {
set_bit(TTYP_FLUSHPENDING, &port->iflags);
mutex_unlock(&buf->flush_mutex);
wait_event(tty->read_wait,
test_bit(TTYP_FLUSHPENDING, &port->iflags) == 0);
return;
}
set_bit(TTYP_FLUSHPENDING, &port->iflags);

mutex_lock(&buf->flush_mutex);
__tty_buffer_flush(port);
clear_bit(TTYP_FLUSHPENDING, &port->iflags);
mutex_unlock(&buf->flush_mutex);
}

Expand Down Expand Up @@ -429,39 +421,26 @@ static void flush_to_ldisc(struct work_struct *work)

mutex_lock(&buf->flush_mutex);

if (!test_and_set_bit(TTYP_FLUSHING, &port->iflags)) {
while (1) {
struct tty_buffer *head = buf->head;
int count;

count = head->commit - head->read;
if (!count) {
if (head->next == NULL)
break;
buf->head = head->next;
tty_buffer_free(port, head);
continue;
}

mutex_unlock(&buf->flush_mutex);

count = receive_buf(tty, head, count);

mutex_lock(&buf->flush_mutex);

/* Ldisc or user is trying to flush the buffers.
We may have a deferred request to flush the
input buffer, if so pull the chain under the lock
and empty the queue */
if (test_bit(TTYP_FLUSHPENDING, &port->iflags)) {
__tty_buffer_flush(port);
clear_bit(TTYP_FLUSHPENDING, &port->iflags);
wake_up(&tty->read_wait);
break;
} else if (!count)
while (1) {
struct tty_buffer *head = buf->head;
int count;

/* Ldisc or user is trying to flush the buffers. */
if (test_bit(TTYP_FLUSHPENDING, &port->iflags))
break;

count = head->commit - head->read;
if (!count) {
if (head->next == NULL)
break;
buf->head = head->next;
tty_buffer_free(port, head);
continue;
}
clear_bit(TTYP_FLUSHING, &port->iflags);

count = receive_buf(tty, head, count);
if (!count)
break;
}

mutex_unlock(&buf->flush_mutex);
Expand Down
1 change: 0 additions & 1 deletion include/linux/tty.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,6 @@ struct tty_port {
wait_queue_head_t delta_msr_wait; /* Modem status change */
unsigned long flags; /* TTY flags ASY_*/
unsigned long iflags; /* TTYP_ internal flags */
#define TTYP_FLUSHING 1 /* Flushing to ldisc in progress */
#define TTYP_FLUSHPENDING 2 /* Queued buffer flush pending */
unsigned char console:1, /* port is a console */
low_latency:1; /* direct buffer flush */
Expand Down

0 comments on commit d7a68be

Please sign in to comment.