Commit d7a68be4 authored by Peter Hurley's avatar Peter Hurley Committed by Greg Kroah-Hartman

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: default avatarPeter Hurley <peter@hurleysoftware.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent e9975fde
...@@ -189,19 +189,11 @@ void tty_buffer_flush(struct tty_struct *tty) ...@@ -189,19 +189,11 @@ void tty_buffer_flush(struct tty_struct *tty)
struct tty_port *port = tty->port; struct tty_port *port = tty->port;
struct tty_bufhead *buf = &port->buf; 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); set_bit(TTYP_FLUSHPENDING, &port->iflags);
mutex_unlock(&buf->flush_mutex);
wait_event(tty->read_wait,
test_bit(TTYP_FLUSHPENDING, &port->iflags) == 0);
return;
}
mutex_lock(&buf->flush_mutex);
__tty_buffer_flush(port); __tty_buffer_flush(port);
clear_bit(TTYP_FLUSHPENDING, &port->iflags);
mutex_unlock(&buf->flush_mutex); mutex_unlock(&buf->flush_mutex);
} }
...@@ -429,11 +421,14 @@ static void flush_to_ldisc(struct work_struct *work) ...@@ -429,11 +421,14 @@ static void flush_to_ldisc(struct work_struct *work)
mutex_lock(&buf->flush_mutex); mutex_lock(&buf->flush_mutex);
if (!test_and_set_bit(TTYP_FLUSHING, &port->iflags)) {
while (1) { while (1) {
struct tty_buffer *head = buf->head; struct tty_buffer *head = buf->head;
int count; int count;
/* Ldisc or user is trying to flush the buffers. */
if (test_bit(TTYP_FLUSHPENDING, &port->iflags))
break;
count = head->commit - head->read; count = head->commit - head->read;
if (!count) { if (!count) {
if (head->next == NULL) if (head->next == NULL)
...@@ -443,25 +438,9 @@ static void flush_to_ldisc(struct work_struct *work) ...@@ -443,25 +438,9 @@ static void flush_to_ldisc(struct work_struct *work)
continue; continue;
} }
mutex_unlock(&buf->flush_mutex);
count = receive_buf(tty, head, count); count = receive_buf(tty, head, count);
if (!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; break;
} else if (!count)
break;
}
clear_bit(TTYP_FLUSHING, &port->iflags);
} }
mutex_unlock(&buf->flush_mutex); mutex_unlock(&buf->flush_mutex);
......
...@@ -213,7 +213,6 @@ struct tty_port { ...@@ -213,7 +213,6 @@ struct tty_port {
wait_queue_head_t delta_msr_wait; /* Modem status change */ wait_queue_head_t delta_msr_wait; /* Modem status change */
unsigned long flags; /* TTY flags ASY_*/ unsigned long flags; /* TTY flags ASY_*/
unsigned long iflags; /* TTYP_ internal flags */ unsigned long iflags; /* TTYP_ internal flags */
#define TTYP_FLUSHING 1 /* Flushing to ldisc in progress */
#define TTYP_FLUSHPENDING 2 /* Queued buffer flush pending */ #define TTYP_FLUSHPENDING 2 /* Queued buffer flush pending */
unsigned char console:1, /* port is a console */ unsigned char console:1, /* port is a console */
low_latency:1; /* direct buffer flush */ low_latency:1; /* direct buffer flush */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment