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 20:02:21 -0400 |
| commit | 019ebdf9f26fd2e43b9e1af576835183e95dc82e (patch) | |
| tree | 805b142ccd2147b65b9ec609057f51c07e55be7c | |
| parent | 17bd79074003d73f2207289b9d3ce0553d000856 (diff) | |
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>
| -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: | |||
| 638 | * are prioritized. Also, when control characters are echoed with a | 638 | * are prioritized. Also, when control characters are echoed with a |
| 639 | * prefixed "^", the pair is treated atomically and thus not separated. | 639 | * prefixed "^", the pair is treated atomically and thus not separated. |
| 640 | * | 640 | * |
| 641 | * Locking: output_lock to protect column state and space left | 641 | * Locking: callers must hold output_lock |
| 642 | */ | 642 | */ |
| 643 | 643 | ||
| 644 | static void process_echoes(struct tty_struct *tty) | 644 | static void __process_echoes(struct tty_struct *tty) |
| 645 | { | 645 | { |
| 646 | struct n_tty_data *ldata = tty->disc_data; | 646 | struct n_tty_data *ldata = tty->disc_data; |
| 647 | int space, nr; | 647 | int space, nr; |
| 648 | size_t tail; | 648 | size_t tail; |
| 649 | unsigned char c; | 649 | unsigned char c; |
| 650 | 650 | ||
| 651 | if (ldata->echo_commit == ldata->echo_tail) | ||
| 652 | return; | ||
| 653 | |||
| 654 | mutex_lock(&ldata->output_lock); | ||
| 655 | |||
| 656 | space = tty_write_room(tty); | 651 | space = tty_write_room(tty); |
| 657 | 652 | ||
| 658 | tail = ldata->echo_tail; | 653 | tail = ldata->echo_tail; |
| @@ -772,20 +767,34 @@ static void process_echoes(struct tty_struct *tty) | |||
| 772 | } | 767 | } |
| 773 | 768 | ||
| 774 | ldata->echo_tail = tail; | 769 | ldata->echo_tail = tail; |
| 770 | } | ||
| 771 | |||
| 772 | static void commit_echoes(struct tty_struct *tty) | ||
| 773 | { | ||
| 774 | struct n_tty_data *ldata = tty->disc_data; | ||
| 775 | 775 | ||
| 776 | mutex_lock(&ldata->output_lock); | ||
| 777 | ldata->echo_commit = ldata->echo_head; | ||
| 778 | __process_echoes(tty); | ||
| 776 | mutex_unlock(&ldata->output_lock); | 779 | mutex_unlock(&ldata->output_lock); |
| 777 | 780 | ||
| 778 | if (tty->ops->flush_chars) | 781 | if (tty->ops->flush_chars) |
| 779 | tty->ops->flush_chars(tty); | 782 | tty->ops->flush_chars(tty); |
| 780 | } | 783 | } |
| 781 | 784 | ||
| 782 | static void commit_echoes(struct tty_struct *tty) | 785 | static void process_echoes(struct tty_struct *tty) |
| 783 | { | 786 | { |
| 784 | struct n_tty_data *ldata = tty->disc_data; | 787 | struct n_tty_data *ldata = tty->disc_data; |
| 785 | 788 | ||
| 786 | smp_mb(); | 789 | if (!L_ECHO(tty) || ldata->echo_commit == ldata->echo_tail) |
| 787 | ldata->echo_commit = ldata->echo_head; | 790 | return; |
| 788 | process_echoes(tty); | 791 | |
| 792 | mutex_lock(&ldata->output_lock); | ||
| 793 | __process_echoes(tty); | ||
| 794 | mutex_unlock(&ldata->output_lock); | ||
| 795 | |||
| 796 | if (tty->ops->flush_chars) | ||
| 797 | tty->ops->flush_chars(tty); | ||
| 789 | } | 798 | } |
| 790 | 799 | ||
| 791 | /** | 800 | /** |
