aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tty_io.c
diff options
context:
space:
mode:
authorJoe Peterson <joe@skyrush.com>2009-01-02 08:40:53 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-02 13:19:35 -0500
commita88a69c91256418c5907c2f1f8a0ec0a36f9e6cc (patch)
treecc595c2c67b1d070e6897bac4098702c164feb39 /drivers/char/tty_io.c
parente482a2378f3d1aef7fa8942f8f163078f01bb456 (diff)
n_tty: Fix loss of echoed characters and remove bkl from n_tty
Fixes the loss of echoed (and other ldisc-generated characters) when the tty is stopped or when the driver output buffer is full (happens frequently for input during continuous program output, such as ^C) and removes the Big Kernel Lock from the N_TTY line discipline. Adds an "echo buffer" to the N_TTY line discipline that handles all ldisc-generated output (including echoed characters). Along with the loss of characters, this also fixes the associated loss of sync between tty output and the ldisc state when characters cannot be immediately written to the tty driver. The echo buffer stores (in addition to characters) state operations that need to be done at the time of character output (like management of the column position). This allows echo to cooperate correctly with program output, since the ldisc state remains consistent with actual characters written. Since the echo buffer code now isolates the tty column state code to the process_out* and process_echoes functions, we can remove the Big Kernel Lock (BKL) and replace it with mutex locks. Highlights are: * Handles echo (and other ldisc output) when tty driver buffer is full - continuous program output can block echo * Saves echo when tty is in stopped state (e.g. ^S) - (e.g.: ^Q will correctly cause held characters to be released for output) * Control character pairs (e.g. "^C") are treated atomically and not split up by interleaved program output * Line discipline state is kept consistent with characters sent to the tty driver * Remove the big kernel lock (BKL) from N_TTY line discipline Signed-off-by: Joe Peterson <joe@skyrush.com> Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/tty_io.c')
-rw-r--r--drivers/char/tty_io.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index db15f9ba7c0b..d8d240c8a25a 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -1111,9 +1111,7 @@ void tty_write_message(struct tty_struct *tty, char *msg)
1111 * Locks the line discipline as required 1111 * Locks the line discipline as required
1112 * Writes to the tty driver are serialized by the atomic_write_lock 1112 * Writes to the tty driver are serialized by the atomic_write_lock
1113 * and are then processed in chunks to the device. The line discipline 1113 * and are then processed in chunks to the device. The line discipline
1114 * write method will not be involked in parallel for each device 1114 * write method will not be invoked in parallel for each device.
1115 * The line discipline write method is called under the big
1116 * kernel lock for historical reasons. New code should not rely on this.
1117 */ 1115 */
1118 1116
1119static ssize_t tty_write(struct file *file, const char __user *buf, 1117static ssize_t tty_write(struct file *file, const char __user *buf,
@@ -2785,6 +2783,8 @@ void initialize_tty_struct(struct tty_struct *tty,
2785 INIT_WORK(&tty->hangup_work, do_tty_hangup); 2783 INIT_WORK(&tty->hangup_work, do_tty_hangup);
2786 mutex_init(&tty->atomic_read_lock); 2784 mutex_init(&tty->atomic_read_lock);
2787 mutex_init(&tty->atomic_write_lock); 2785 mutex_init(&tty->atomic_write_lock);
2786 mutex_init(&tty->output_lock);
2787 mutex_init(&tty->echo_lock);
2788 spin_lock_init(&tty->read_lock); 2788 spin_lock_init(&tty->read_lock);
2789 spin_lock_init(&tty->ctrl_lock); 2789 spin_lock_init(&tty->ctrl_lock);
2790 INIT_LIST_HEAD(&tty->tty_files); 2790 INIT_LIST_HEAD(&tty->tty_files);