All of lore.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: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-07-25 22:57 - utc-timestamp-option-for-fat-filesystems-fix.patch removed from -mm tree akpm
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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.