diff options
author | Peter Hurley <peter@hurleysoftware.com> | 2013-06-15 10:04:25 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-07-23 17:02:21 -0700 |
commit | 019ebdf9f26fd2e43b9e1af576835183e95dc82e (patch) | |
tree | 805b142ccd2147b65b9ec609057f51c07e55be7c /drivers/tty/n_tty.c | |
parent | 17bd79074003d73f2207289b9d3ce0553d000856 (diff) | |
download | blackbird-op-linux-019ebdf9f26fd2e43b9e1af576835183e95dc82e.tar.gz blackbird-op-linux-019ebdf9f26fd2e43b9e1af576835183e95dc82e.zip |
n_tty: Eliminate echo_commit memory barrier
Use output_lock mutex as a memory barrier when storing echo_commit.
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/n_tty.c')
-rw-r--r-- | drivers/tty/n_tty.c | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 3b499451b7ed..0f76b9096840 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -638,21 +638,16 @@ break_out: * are prioritized. Also, when control characters are echoed with a * prefixed "^", the pair is treated atomically and thus not separated. * - * Locking: output_lock to protect column state and space left + * Locking: callers must hold output_lock */ -static void process_echoes(struct tty_struct *tty) +static void __process_echoes(struct tty_struct *tty) { struct n_tty_data *ldata = tty->disc_data; int space, nr; size_t tail; unsigned char c; - if (ldata->echo_commit == ldata->echo_tail) - return; - - mutex_lock(&ldata->output_lock); - space = tty_write_room(tty); tail = ldata->echo_tail; @@ -772,20 +767,34 @@ static void process_echoes(struct tty_struct *tty) } ldata->echo_tail = tail; +} + +static void commit_echoes(struct tty_struct *tty) +{ + struct n_tty_data *ldata = tty->disc_data; + mutex_lock(&ldata->output_lock); + ldata->echo_commit = ldata->echo_head; + __process_echoes(tty); mutex_unlock(&ldata->output_lock); if (tty->ops->flush_chars) tty->ops->flush_chars(tty); } -static void commit_echoes(struct tty_struct *tty) +static void process_echoes(struct tty_struct *tty) { struct n_tty_data *ldata = tty->disc_data; - smp_mb(); - ldata->echo_commit = ldata->echo_head; - process_echoes(tty); + if (!L_ECHO(tty) || ldata->echo_commit == ldata->echo_tail) + return; + + mutex_lock(&ldata->output_lock); + __process_echoes(tty); + mutex_unlock(&ldata->output_lock); + + if (tty->ops->flush_chars) + tty->ops->flush_chars(tty); } /** |