public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Joe Peterson <joe@skyrush.com>
To: akpm@linux-foundation.org
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>,
	Linux Kernel <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] TTY: Fix loss of echoed characters
Date: Tue, 26 Aug 2008 06:41:27 -0600	[thread overview]
Message-ID: <48B3F9F7.2050503@skyrush.com> (raw)
In-Reply-To: <48AC3A16.4080209@skyrush.com>

[-- Attachment #1: Type: text/plain, Size: 397 bytes --]

Joe Peterson wrote:
> Andrew, attached is a patch that fixes the loss of echoed characters in
> two common cases: 1) tty output buffer is full due to lots of output and
> 2) tty is stopped.

Attached is a follow-on patch.  It just does some code style cleanup and
minor code efficiency tweaks.  Please apply it after the main patch
(probably should be combined into one patch).

						Thanks, Joe

[-- Attachment #2: tty-fix-loss-of-echoed-characters-cleanup.patch --]
[-- Type: text/plain, Size: 4012 bytes --]

Minor code efficiency and style cleanup.  No behavior changes.
Apply after tty-fix-loss-of-echoed-characters.patch.

Signed-off-by: Joe Peterson <joe@skyrush.com>
---

--- linux/drivers/char/n_tty.c.orig	2008-08-20 18:19:06.000000000 -0600
+++ linux/drivers/char/n_tty.c	2008-08-25 13:41:30.000000000 -0600
@@ -446,8 +446,6 @@ static ssize_t process_output_block(stru
 		}
 	}
 break_out:
-	//if (tty->ops->flush_chars)
-	//	tty->ops->flush_chars(tty);
 	i = tty->ops->write(tty, buf, i);
 
 	unlock_kernel();
@@ -455,11 +453,11 @@ break_out:
 }
 
 /**
- *	process_echoes	-	write pending echoed characters
+ *	process_echoes	-	write pending echo characters
  *	@tty: terminal device
  *
- *	Write echoed (and other ldisc-generated) characters to the
- *	tty that have been stored previously in the echo buffer.
+ *	Write previously buffered echo (and other ldisc-generated)
+ *	characters to the tty.
  *
  *	Characters generated by the ldisc (including echoes) need to
  *	be buffered because the driver's write buffer can fill during
@@ -488,11 +486,11 @@ break_out:
 
 static void process_echoes(struct tty_struct *tty)
 {
-	int	space, num, nr;
+	int	space, nr;
 	unsigned char c;
 	unsigned char *cp, *buf_end;
 
-	if (!(num = tty->echo_cnt))
+	if (!tty->echo_cnt)
 		return;
 
 	lock_kernel();
@@ -501,7 +499,7 @@ static void process_echoes(struct tty_st
 
 	buf_end = tty->echo_buf + N_TTY_BUF_SIZE;
 	cp = tty->echo_buf + tty->echo_pos;
-	nr = num;
+	nr = tty->echo_cnt;
 	while (nr > 0) {
 		c = *cp;
 		if (c == ECHO_OP_START) {
@@ -635,14 +633,15 @@ static void process_echoes(struct tty_st
 			cp -= N_TTY_BUF_SIZE;
 	}
 
-	tty->echo_cnt = nr;
-	if (tty->echo_cnt == 0) {
+	if (nr == 0) {
 		tty->echo_pos = 0;
+		tty->echo_cnt = 0;
 		tty->echo_overrun = 0;
 	} else {
-		int num_processed = (num - nr);
+		int num_processed = tty->echo_cnt - nr;
 		tty->echo_pos += num_processed;
-		tty->echo_pos &= (N_TTY_BUF_SIZE - 1);
+		tty->echo_pos &= N_TTY_BUF_SIZE - 1;
+		tty->echo_cnt = nr;
 		if (num_processed > 0)
 			tty->echo_overrun = 0;
 	}
@@ -663,42 +662,43 @@ static void process_echoes(struct tty_st
 
 static void add_echo_byte(unsigned char c, struct tty_struct *tty)
 {
-	int 	add_char_pos;
+	int	new_byte_pos;
 	unsigned long flags;
 
 	spin_lock_irqsave(&tty->echo_lock, flags);
 
-	add_char_pos = tty->echo_pos + tty->echo_cnt;
-	if (add_char_pos >= N_TTY_BUF_SIZE)
-		add_char_pos -= N_TTY_BUF_SIZE;
-
-	/* Detect overrun */
 	if (tty->echo_cnt == N_TTY_BUF_SIZE) {
+		/* Circular buffer is already at capacity */
+		new_byte_pos = tty->echo_pos;
+
 		/*
-		 * If the start position pointer needs to be advanced
-		 * due to running out of buffer space, be sure it is
-		 * done in such a way as to remove whole
-		 * operation byte groups.
+		 * Since the buffer start position needs to be advanced,
+		 * be sure to step by a whole operation byte group.
 		 */
-		if (*(tty->echo_buf +
-		      (tty->echo_pos & (N_TTY_BUF_SIZE - 1))) == ECHO_OP_START)
+		if (tty->echo_buf[tty->echo_pos] == ECHO_OP_START)
 		{
-			if (*(tty->echo_buf +
-			      ((tty->echo_pos + 1) & (N_TTY_BUF_SIZE - 1))) == ECHO_OP_TAB_ERASE) {
+			if (tty->echo_buf[(tty->echo_pos + 1) &
+					  (N_TTY_BUF_SIZE - 1)] ==
+						ECHO_OP_TAB_ERASE) {
 				tty->echo_pos += 4;
 				tty->echo_cnt -= 3;
 			} else {
 				tty->echo_pos += 2;
 				tty->echo_cnt -= 1;
 			}
-		} else
+		} else {
 			tty->echo_pos++;
-		tty->echo_pos &= (N_TTY_BUF_SIZE - 1);
+		}
+		tty->echo_pos &= N_TTY_BUF_SIZE - 1;
+
 		tty->echo_overrun = 1;
-	} else
+	} else {
+		new_byte_pos = tty->echo_pos + tty->echo_cnt;
+		new_byte_pos &= N_TTY_BUF_SIZE - 1;
 		tty->echo_cnt++;
+	}
 
-	tty->echo_buf[add_char_pos] = c;
+	tty->echo_buf[new_byte_pos] = c;
 
 	spin_unlock_irqrestore(&tty->echo_lock, flags);
 }
@@ -762,8 +762,9 @@ static void echo_char_raw(unsigned char 
 	if (c == ECHO_OP_START) {
 		add_echo_byte(ECHO_OP_START, tty);
 		add_echo_byte(ECHO_OP_START, tty);
-	} else
+	} else {
 		add_echo_byte(c, tty);
+	}
 }
 
 /**

  reply	other threads:[~2008-08-26 12:41 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <200807252257.m6PMvieO003213@imap1.linux-foundation.org>
2008-08-20 15:36 ` [PATCH] TTY: Fix loss of echoed characters Joe Peterson
2008-08-26 12:41   ` Joe Peterson [this message]
2008-09-08 16:11     ` [PATCH] TTY: Fix loss of echoed characters (2nd follow-on PATCH attached) Joe Peterson
2008-09-09  0:32       ` Andrew Morton
2008-09-09 10:55         ` Alan Cox
2008-09-09 17:43           ` Andrew Morton
2008-09-09 20:42             ` Joe Peterson
2008-09-10 23:39               ` Andrew Morton
2008-09-11 12:53                 ` Joe Peterson
2008-09-09 13:00         ` Joe Peterson
2008-09-09 13:12           ` Alan Cox
2008-09-09 13:15             ` Joe Peterson
2008-09-09 13:19               ` Alan Cox

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=48B3F9F7.2050503@skyrush.com \
    --to=joe@skyrush.com \
    --cc=akpm@linux-foundation.org \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox