All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Hurley <peter@hurleysoftware.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Jiri Slaby <jslaby@suse.cz>
Cc: Min Zhang <mzhang@mvista.com>,
	linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org,
	Peter Hurley <peter@hurleysoftware.com>
Subject: [PATCH 14/18] n_tty: Make N_TTY ldisc receive path lockless
Date: Tue, 19 Mar 2013 16:21:49 -0400	[thread overview]
Message-ID: <1363724513-15604-15-git-send-email-peter@hurleysoftware.com> (raw)
In-Reply-To: <1363724513-15604-1-git-send-email-peter@hurleysoftware.com>

n_tty has a single-producer/single-consumer input model;
use lockless publish instead.

Use termios_rwsem to exclude both consumer and producer while
changing or resetting buffer indices, eg., when flushing. Also,
claim exclusive termios_rwsem to safely retrieve the buffer
indices from a thread other than consumer or producer
(eg., TIOCINQ ioctl).

Note the read_tail is published _after_ clearing the newline
indicator in read_flags to avoid racing the producer.

Drop read_lock spinlock.

Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
---
 drivers/tty/n_tty.c | 178 ++++++++++++++++++++++++++++------------------------
 1 file changed, 96 insertions(+), 82 deletions(-)

diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index 2a3ab63..b1b934c 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -113,7 +113,6 @@ struct n_tty_data {
 	struct mutex atomic_read_lock;
 	struct mutex output_lock;
 	struct mutex echo_lock;
-	raw_spinlock_t read_lock;
 };
 
 static inline size_t read_cnt(struct n_tty_data *ldata)
@@ -171,7 +170,10 @@ static ssize_t receive_room(struct tty_struct *tty)
  *
  *	Re-schedules the flip buffer work if space just became available.
  *
- *	Locks: Concurrent update is protected with read_lock
+ *	Caller holds exclusive termios_rwsem
+ *	   or
+ *	n_tty_read()/consumer path:
+ *		holds non-exclusive termios_rwsem
  */
 
 static void n_tty_set_room(struct tty_struct *tty)
@@ -199,48 +201,45 @@ static void n_tty_set_room(struct tty_struct *tty)
  *	Called by flush_to_ldisc() to determine the currently
  *	available space in the input buffer.
  *
- *	Locks: Concurrent update is protected with read_lock
+ *	flush_to_ldisc()/producer path:
+ *		claim non-exclusive termios_rwsem
  */
 
 static ssize_t n_tty_receive_room(struct tty_struct *tty)
 {
 	struct n_tty_data *ldata = tty->disc_data;
+	ssize_t room;
 
-	ssize_t room = receive_room(tty);
+	down_read(&tty->termios_rwsem);
+	room = receive_room(tty);
+	up_read(&tty->termios_rwsem);
 	if (!room)
 		__set_bit(NO_ROOM, &ldata->flags);
 
 	return room;
 }
 
-static void put_tty_queue_nolock(unsigned char c, struct n_tty_data *ldata)
-{
-	if (read_cnt(ldata) < N_TTY_BUF_SIZE) {
-		*read_buf_addr(ldata, ldata->read_head) = c;
-		ldata->read_head++;
-	}
-}
-
 /**
  *	put_tty_queue		-	add character to tty
  *	@c: character
  *	@ldata: n_tty data
  *
- *	Add a character to the tty read_buf queue. This is done under the
- *	read_lock to serialize character addition and also to protect us
- *	against parallel reads or flushes
+ *	Add a character to the tty read_buf queue.
+ *
+ *	n_tty_receive_buf()/producer path:
+ *		caller holds non-exclusive termios_rwsem
+ *		modifies read_head
+ *
+ *	read_head is only considered 'published' if canonical mode is
+ *	not active.
  */
 
 static void put_tty_queue(unsigned char c, struct n_tty_data *ldata)
 {
-	unsigned long flags;
-	/*
-	 *	The problem of stomping on the buffers ends here.
-	 *	Why didn't anyone see this one coming? --AJK
-	*/
-	raw_spin_lock_irqsave(&ldata->read_lock, flags);
-	put_tty_queue_nolock(c, ldata);
-	raw_spin_unlock_irqrestore(&ldata->read_lock, flags);
+	if (read_cnt(ldata) < N_TTY_BUF_SIZE) {
+		*read_buf_addr(ldata, ldata->read_head) = c;
+		ldata->read_head++;
+	}
 }
 
 /**
@@ -250,16 +249,13 @@ static void put_tty_queue(unsigned char c, struct n_tty_data *ldata)
  *	Reset the read buffer counters and clear the flags.
  *	Called from n_tty_open() and n_tty_flush_buffer().
  *
- *	Locking: tty_read_lock for read fields.
+ *	Locking: caller holds exclusive termios_rwsem
+ *		 (or locking is not required)
  */
 
 static void reset_buffer_flags(struct n_tty_data *ldata)
 {
-	unsigned long flags;
-
-	raw_spin_lock_irqsave(&ldata->read_lock, flags);
 	ldata->read_head = ldata->canon_head = ldata->read_tail = 0;
-	raw_spin_unlock_irqrestore(&ldata->read_lock, flags);
 
 	mutex_lock(&ldata->echo_lock);
 	ldata->echo_pos = ldata->echo_cnt = ldata->echo_overrun = 0;
@@ -289,47 +285,55 @@ static void n_tty_packet_mode_flush(struct tty_struct *tty)
  *	buffer flushed (eg at hangup) or when the N_TTY line discipline
  *	internally has to clean the pending queue (for example some signals).
  *
- *	Locking: ctrl_lock, read_lock.
+ *	Holds termios_rwsem to exclude producer/consumer while
+ *	buffer indices are reset.
+ *
+ *	Locking: ctrl_lock, exclusive termios_rwsem
  */
 
 static void n_tty_flush_buffer(struct tty_struct *tty)
 {
+	down_write(&tty->termios_rwsem);
 	reset_buffer_flags(tty->disc_data);
 	n_tty_set_room(tty);
 
 	if (tty->link)
 		n_tty_packet_mode_flush(tty);
+	up_write(&tty->termios_rwsem);
 }
 
-/**
- *	n_tty_chars_in_buffer	-	report available bytes
- *	@tty: tty device
- *
- *	Report the number of characters buffered to be delivered to user
- *	at this instant in time.
- *
- *	Locking: read_lock
- */
-
 static ssize_t chars_in_buffer(struct tty_struct *tty)
 {
 	struct n_tty_data *ldata = tty->disc_data;
-	unsigned long flags;
 	ssize_t n = 0;
 
-	raw_spin_lock_irqsave(&ldata->read_lock, flags);
 	if (!ldata->icanon)
 		n = read_cnt(ldata);
 	else
 		n = ldata->canon_head - ldata->read_tail;
-	raw_spin_unlock_irqrestore(&ldata->read_lock, flags);
 	return n;
 }
 
+/**
+ *	n_tty_chars_in_buffer	-	report available bytes
+ *	@tty: tty device
+ *
+ *	Report the number of characters buffered to be delivered to user
+ *	at this instant in time.
+ *
+ *	Locking: exclusive termios_rwsem
+ */
+
 static ssize_t n_tty_chars_in_buffer(struct tty_struct *tty)
 {
+	ssize_t n;
+
 	WARN_ONCE(1, "%s is deprecated and scheduled for removal.", __func__);
-	return chars_in_buffer(tty);
+
+	down_write(&tty->termios_rwsem);
+	n = chars_in_buffer(tty);
+	up_write(&tty->termios_rwsem);
+	return n;
 }
 
 /**
@@ -938,7 +942,12 @@ static inline void finish_erasing(struct n_tty_data *ldata)
  *	present in the stream from the driver layer. Handles the complexities
  *	of UTF-8 multibyte symbols.
  *
- *	Locking: read_lock for tty buffers
+ *	n_tty_receive_buf()/producer path:
+ *		caller holds non-exclusive termios_rwsem
+ *		modifies read_head
+ *
+ *	Modifying the read_head is not considered a publish in this context
+ *	because canonical mode is active -- only canon_head publishes
  */
 
 static void eraser(unsigned char c, struct tty_struct *tty)
@@ -948,9 +957,7 @@ static void eraser(unsigned char c, struct tty_struct *tty)
 	size_t head;
 	size_t cnt;
 	int seen_alnums;
-	unsigned long flags;
 
-	/* FIXME: locking needed ? */
 	if (ldata->read_head == ldata->canon_head) {
 		/* process_output('\a', tty); */ /* what do you think? */
 		return;
@@ -961,15 +968,11 @@ static void eraser(unsigned char c, struct tty_struct *tty)
 		kill_type = WERASE;
 	else {
 		if (!L_ECHO(tty)) {
-			raw_spin_lock_irqsave(&ldata->read_lock, flags);
 			ldata->read_head = ldata->canon_head;
-			raw_spin_unlock_irqrestore(&ldata->read_lock, flags);
 			return;
 		}
 		if (!L_ECHOK(tty) || !L_ECHOKE(tty) || !L_ECHOE(tty)) {
-			raw_spin_lock_irqsave(&ldata->read_lock, flags);
 			ldata->read_head = ldata->canon_head;
-			raw_spin_unlock_irqrestore(&ldata->read_lock, flags);
 			finish_erasing(ldata);
 			echo_char(KILL_CHAR(tty), tty);
 			/* Add a newline if ECHOK is on and ECHOKE is off. */
@@ -981,7 +984,6 @@ static void eraser(unsigned char c, struct tty_struct *tty)
 	}
 
 	seen_alnums = 0;
-	/* FIXME: Locking ?? */
 	while (ldata->read_head != ldata->canon_head) {
 		head = ldata->read_head;
 
@@ -1003,9 +1005,7 @@ static void eraser(unsigned char c, struct tty_struct *tty)
 				break;
 		}
 		cnt = ldata->read_head - head;
-		raw_spin_lock_irqsave(&ldata->read_lock, flags);
 		ldata->read_head = head;
-		raw_spin_unlock_irqrestore(&ldata->read_lock, flags);
 		if (L_ECHO(tty)) {
 			if (L_ECHOPRT(tty)) {
 				if (!ldata->erasing) {
@@ -1094,7 +1094,11 @@ static inline void isig(int sig, struct tty_struct *tty)
  *	An RS232 break event has been hit in the incoming bitstream. This
  *	can cause a variety of events depending upon the termios settings.
  *
- *	Called from the receive_buf path so single threaded.
+ *	n_tty_receive_buf()/producer path:
+ *		caller holds non-exclusive termios_rwsem
+ *		publishes read_head via put_tty_queue()
+ *
+ *	Note: may get exclusive termios_rwsem if flushing input buffer
  */
 
 static inline void n_tty_receive_break(struct tty_struct *tty)
@@ -1106,8 +1110,11 @@ static inline void n_tty_receive_break(struct tty_struct *tty)
 	if (I_BRKINT(tty)) {
 		isig(SIGINT, tty);
 		if (!L_NOFLSH(tty)) {
+			/* flushing needs exclusive termios_rwsem */
+			up_read(&tty->termios_rwsem);
 			n_tty_flush_buffer(tty);
 			tty_driver_flush_buffer(tty);
+			down_read(&tty->termios_rwsem);
 		}
 		return;
 	}
@@ -1154,7 +1161,11 @@ static inline void n_tty_receive_overrun(struct tty_struct *tty)
  *	@c: character
  *
  *	Process a parity error and queue the right data to indicate
- *	the error case if necessary. Locking as per n_tty_receive_buf.
+ *	the error case if necessary.
+ *
+ *	n_tty_receive_buf()/producer path:
+ *		caller holds non-exclusive termios_rwsem
+ *		publishes read_head via put_tty_queue()
  */
 static inline void n_tty_receive_parity_error(struct tty_struct *tty,
 					      unsigned char c)
@@ -1182,12 +1193,16 @@ static inline void n_tty_receive_parity_error(struct tty_struct *tty,
  *	Process an individual character of input received from the driver.
  *	This is serialized with respect to itself by the rules for the
  *	driver above.
+ *
+ *	n_tty_receive_buf()/producer path:
+ *		caller holds non-exclusive termios_rwsem
+ *		publishes canon_head if canonical mode is active
+ *		otherwise, publishes read_head via put_tty_queue()
  */
 
 static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
 {
 	struct n_tty_data *ldata = tty->disc_data;
-	unsigned long flags;
 	int parmrk;
 
 	if (ldata->raw) {
@@ -1276,8 +1291,11 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
 		if (c == SUSP_CHAR(tty)) {
 send_signal:
 			if (!L_NOFLSH(tty)) {
+				/* flushing needs exclusive termios_rwsem */
+				up_read(&tty->termios_rwsem);
 				n_tty_flush_buffer(tty);
 				tty_driver_flush_buffer(tty);
+				down_read(&tty->termios_rwsem);
 			}
 			if (I_IXON(tty))
 				start_tty(tty);
@@ -1378,11 +1396,9 @@ send_signal:
 				put_tty_queue(c, ldata);
 
 handle_newline:
-			raw_spin_lock_irqsave(&ldata->read_lock, flags);
 			set_bit(ldata->read_head & (N_TTY_BUF_SIZE - 1), ldata->read_flags);
-			put_tty_queue_nolock(c, ldata);
+			put_tty_queue(c, ldata);
 			ldata->canon_head = ldata->read_head;
-			raw_spin_unlock_irqrestore(&ldata->read_lock, flags);
 			kill_fasync(&tty->fasync, SIGIO, POLL_IN);
 			if (waitqueue_active(&tty->read_wait))
 				wake_up_interruptible(&tty->read_wait);
@@ -1443,6 +1459,10 @@ static void n_tty_write_wakeup(struct tty_struct *tty)
  *	been received. This function must be called from soft contexts
  *	not from interrupt context. The driver is responsible for making
  *	calls one at a time and in order (or using flush_to_ldisc)
+ *
+ *	n_tty_receive_buf()/producer path:
+ *		claims non-exclusive termios_rwsem
+ *		publishes read_head and canon_head
  */
 
 static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
@@ -1453,12 +1473,10 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
 	char *f, flags = TTY_NORMAL;
 	int	i;
 	char	buf[64];
-	unsigned long cpuflags;
 
 	down_read(&tty->termios_rwsem);
 
 	if (ldata->real_raw) {
-		raw_spin_lock_irqsave(&ldata->read_lock, cpuflags);
 		i = min(N_TTY_BUF_SIZE - read_cnt(ldata),
 			N_TTY_BUF_SIZE - (ldata->read_head & (N_TTY_BUF_SIZE - 1)));
 		i = min(count, i);
@@ -1472,7 +1490,6 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
 		i = min(count, i);
 		memcpy(read_buf_addr(ldata, ldata->read_head), cp, i);
 		ldata->read_head += i;
-		raw_spin_unlock_irqrestore(&ldata->read_lock, cpuflags);
 	} else {
 		for (i = count, p = cp, f = fp; i; i--, p++) {
 			if (f)
@@ -1673,7 +1690,6 @@ static int n_tty_open(struct tty_struct *tty)
 	mutex_init(&ldata->atomic_read_lock);
 	mutex_init(&ldata->output_lock);
 	mutex_init(&ldata->echo_lock);
-	raw_spin_lock_init(&ldata->read_lock);
 
 	/* These are ugly. Currently a malloc failure here can panic */
 	ldata->read_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL);
@@ -1729,6 +1745,9 @@ static inline int input_available_p(struct tty_struct *tty, int amt)
  *
  *	Called under the ldata->atomic_read_lock sem
  *
+ *	n_tty_read()/consumer path:
+ *		caller holds non-exclusive termios_rwsem
+ *		read_tail published
  */
 
 static int copy_from_read_buf(struct tty_struct *tty,
@@ -1739,27 +1758,22 @@ static int copy_from_read_buf(struct tty_struct *tty,
 	struct n_tty_data *ldata = tty->disc_data;
 	int retval;
 	size_t n;
-	unsigned long flags;
 	bool is_eof;
 	size_t tail = ldata->read_tail & (N_TTY_BUF_SIZE - 1);
 
 	retval = 0;
-	raw_spin_lock_irqsave(&ldata->read_lock, flags);
 	n = min(read_cnt(ldata), N_TTY_BUF_SIZE - tail);
 	n = min(*nr, n);
-	raw_spin_unlock_irqrestore(&ldata->read_lock, flags);
 	if (n) {
 		retval = copy_to_user(*b, read_buf_addr(ldata, tail), n);
 		n -= retval;
 		is_eof = n == 1 && read_buf(ldata, tail) == EOF_CHAR(tty);
 		tty_audit_add_data(tty, read_buf_addr(ldata, tail), n,
 				ldata->icanon);
-		raw_spin_lock_irqsave(&ldata->read_lock, flags);
 		ldata->read_tail += n;
 		/* Turn single EOF into zero-length read */
 		if (L_EXTPROC(tty) && ldata->icanon && is_eof && !read_cnt(ldata))
 			n = 0;
-		raw_spin_unlock_irqrestore(&ldata->read_lock, flags);
 		*b += n;
 		*nr -= n;
 	}
@@ -1777,6 +1791,10 @@ static int copy_from_read_buf(struct tty_struct *tty,
  *	character into the user-space buffer.
  *
  *	Called under the atomic_read_lock mutex
+ *
+ *	n_tty_read()/consumer path:
+ *		caller holds non-exclusive termios_rwsem
+ *		read_tail published
  */
 
 static int canon_copy_from_read_buf(struct tty_struct *tty,
@@ -1784,21 +1802,15 @@ static int canon_copy_from_read_buf(struct tty_struct *tty,
 				    size_t *nr)
 {
 	struct n_tty_data *ldata = tty->disc_data;
-	unsigned long flags;
 	size_t n, size, more, c;
 	size_t eol;
 	size_t tail;
 	int ret, found = 0;
 
 	/* N.B. avoid overrun if nr == 0 */
-
-	raw_spin_lock_irqsave(&ldata->read_lock, flags);
-
 	n = min(*nr, read_cnt(ldata));
-	if (!n) {
-		raw_spin_unlock_irqrestore(&ldata->read_lock, flags);
+	if (!n)
 		return 0;
-	}
 
 	tail = ldata->read_tail & (N_TTY_BUF_SIZE - 1);
 	size = min_t(size_t, tail + n, N_TTY_BUF_SIZE);
@@ -1826,8 +1838,6 @@ static int canon_copy_from_read_buf(struct tty_struct *tty,
 	n_tty_trace("%s: eol:%zu found:%d n:%zu c:%zu size:%zu more:%zu\n",
 		    __func__, eol, found, n, c, size, more);
 
-	raw_spin_unlock_irqrestore(&ldata->read_lock, flags);
-
 	if (n > size) {
 		ret = copy_to_user(*b, read_buf_addr(ldata, tail), size);
 		if (ret)
@@ -1841,11 +1851,9 @@ static int canon_copy_from_read_buf(struct tty_struct *tty,
 	*b += n;
 	*nr -= n;
 
-	raw_spin_lock_irqsave(&ldata->read_lock, flags);
-	ldata->read_tail += c;
 	if (found)
 		__clear_bit(eol, ldata->read_flags);
-	raw_spin_unlock_irqrestore(&ldata->read_lock, flags);
+	ldata->read_tail += c;
 
 	if (found)
 		tty_audit_push(tty);
@@ -1909,6 +1917,10 @@ static int job_control(struct tty_struct *tty, struct file *file)
  *	a hangup. Always called in user context, may sleep.
  *
  *	This code must be sure never to sleep through a hangup.
+ *
+ *	n_tty_read()/consumer path:
+ *		claims non-exclusive termios_rwsem
+ *		publishes read_tail
  */
 
 static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
@@ -2268,10 +2280,12 @@ static int n_tty_ioctl(struct tty_struct *tty, struct file *file,
 	case TIOCOUTQ:
 		return put_user(tty_chars_in_buffer(tty), (int __user *) arg);
 	case TIOCINQ:
-		/* FIXME: Locking */
-		retval = read_cnt(ldata);
+		down_write(&tty->termios_rwsem);
 		if (L_ICANON(tty))
 			retval = inq_canon(ldata);
+		else
+			retval = read_cnt(ldata);
+		up_write(&tty->termios_rwsem);
 		return put_user(retval, (unsigned int __user *) arg);
 	default:
 		return n_tty_ioctl_helper(tty, file, cmd, arg);
-- 
1.8.1.2

  parent reply	other threads:[~2013-03-19 20:21 UTC|newest]

Thread overview: 239+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-03-19 20:21 [PATCH 00/18] lockless n_tty receive path Peter Hurley
2013-03-19 20:21 ` [PATCH 01/18] tty: Don't change receive_room for ioctl(TIOCSETD) Peter Hurley
2013-03-19 20:21 ` [PATCH 02/18] tty: Make ldisc input flow control concurrency-friendly Peter Hurley
2013-03-19 20:21 ` [PATCH 03/18] tty: Simplify tty buffer/ldisc interface with helper function Peter Hurley
2013-03-19 22:42   ` Ilya Zykov
2013-03-19 23:50     ` Peter Hurley
2013-03-20 12:47       ` Ilya Zykov
2013-03-20 17:20         ` [PATCH] tty: Fix race condition if flushing tty flip buffers Peter Hurley
2013-03-20 17:56           ` Ilya Zykov
2013-04-08 18:48           ` Greg Kroah-Hartman
2013-04-08 20:03             ` Peter Hurley
2013-03-20 17:49         ` [PATCH 03/18] tty: Simplify tty buffer/ldisc interface with helper function Peter Hurley
2013-03-20 19:25           ` Ilya Zykov
2013-03-19 20:21 ` [PATCH 04/18] n_tty: Factor canonical mode copy from n_tty_read() Peter Hurley
2013-03-19 20:21 ` [PATCH 05/18] n_tty: Line copy to user buffer in canonical mode Peter Hurley
2013-03-19 20:21 ` [PATCH 06/18] n_tty: Split n_tty_chars_in_buffer() for reader-only interface Peter Hurley
2013-03-19 20:21 ` [PATCH 07/18] tty: Deprecate ldisc .chars_in_buffer() method Peter Hurley
2013-03-19 20:21 ` [PATCH 08/18] n_tty: Get read_cnt through accessor Peter Hurley
2013-03-19 20:21 ` [PATCH 09/18] n_tty: Don't wrap input buffer indices at buffer size Peter Hurley
2013-03-19 20:21 ` [PATCH 10/18] n_tty: Remove read_cnt Peter Hurley
2013-03-19 20:21 ` [PATCH 11/18] tty: Convert termios_mutex to termios_rwsem Peter Hurley
2013-03-19 20:21 ` [PATCH 12/18] n_tty: Access termios values safely Peter Hurley
2013-03-19 20:21 ` [PATCH 13/18] n_tty: Replace canon_data with index comparison Peter Hurley
2013-03-19 20:21 ` Peter Hurley [this message]
2013-03-19 20:21 ` [PATCH 15/18] n_tty: Reset lnext if canonical mode changes Peter Hurley
2013-03-19 20:21 ` [PATCH 16/18] n_tty: Fix type mismatches in receive_buf raw copy Peter Hurley
2013-03-19 20:21 ` [PATCH 17/18] n_tty: Don't wait for buffer work in read() loop Peter Hurley
2013-03-19 20:21 ` [PATCH 18/18] n_tty: Separate buffer indices to prevent cache-line sharing Peter Hurley
2013-03-27 11:43 ` [PATCH v2 00/18] lockless n_tty receive path Peter Hurley
2013-03-27 11:43   ` [PATCH v2 01/18] tty: Don't change receive_room for ioctl(TIOCSETD) Peter Hurley
2013-03-27 11:43   ` [PATCH v2 02/18] tty: Make ldisc input flow control concurrency-friendly Peter Hurley
2013-03-27 11:43   ` [PATCH v2 03/18] tty: Simplify tty buffer/ldisc interface with helper function Peter Hurley
2013-03-27 11:43   ` [PATCH v2 04/18] n_tty: Factor canonical mode copy from n_tty_read() Peter Hurley
2013-03-27 11:43   ` [PATCH v2 05/18] n_tty: Line copy to user buffer in canonical mode Peter Hurley
2013-03-27 11:43   ` [PATCH v2 06/18] n_tty: Split n_tty_chars_in_buffer() for reader-only interface Peter Hurley
2013-03-27 11:43   ` [PATCH v2 07/18] tty: Deprecate ldisc .chars_in_buffer() method Peter Hurley
2013-03-27 11:43   ` [PATCH v2 08/18] n_tty: Get read_cnt through accessor Peter Hurley
2013-03-27 11:43   ` [PATCH v2 09/18] n_tty: Don't wrap input buffer indices at buffer size Peter Hurley
2013-03-27 11:44   ` [PATCH v2 10/18] n_tty: Remove read_cnt Peter Hurley
2013-03-27 11:44   ` [PATCH v2 11/18] tty: Convert termios_mutex to termios_rwsem Peter Hurley
2013-03-27 11:44   ` [PATCH v2 12/18] n_tty: Access termios values safely Peter Hurley
2013-03-27 11:44   ` [PATCH v2 13/18] n_tty: Replace canon_data with index comparison Peter Hurley
2013-03-27 11:44   ` [PATCH v2 14/18] n_tty: Make N_TTY ldisc receive path lockless Peter Hurley
2013-03-27 11:44   ` [PATCH v2 15/18] n_tty: Reset lnext if canonical mode changes Peter Hurley
2013-03-27 11:44   ` [PATCH v2 16/18] n_tty: Fix type mismatches in receive_buf raw copy Peter Hurley
2013-03-27 11:44   ` [PATCH v2 17/18] n_tty: Don't wait for buffer work in read() loop Peter Hurley
2013-03-27 11:44   ` [PATCH v2 18/18] n_tty: Separate buffer indices to prevent cache-line sharing Peter Hurley
2013-03-27 11:46   ` [PATCH v2 00/18] lockless n_tty receive path Peter Hurley
2013-04-15 15:19 ` [PATCH v3 00/24] " Peter Hurley
2013-04-15 15:19   ` [PATCH v3 01/24] tty: Don't change receive_room for ioctl(TIOCSETD) Peter Hurley
2013-04-15 15:19   ` [PATCH v3 02/24] tty: Simplify tty buffer/ldisc interface with helper function Peter Hurley
2013-04-15 15:19   ` [PATCH v3 03/24] tty: Make ldisc input flow control concurrency-friendly Peter Hurley
2013-04-15 15:19   ` [PATCH v3 04/24] n_tty: Factor canonical mode copy from n_tty_read() Peter Hurley
2013-04-15 15:19   ` [PATCH v3 05/24] n_tty: Line copy to user buffer in canonical mode Peter Hurley
2013-04-15 15:19   ` [PATCH v3 06/24] n_tty: Split n_tty_chars_in_buffer() for reader-only interface Peter Hurley
2013-04-15 15:19   ` [PATCH v3 07/24] tty: Deprecate ldisc .chars_in_buffer() method Peter Hurley
2013-04-15 15:19   ` [PATCH v3 08/24] n_tty: Get read_cnt through accessor Peter Hurley
2013-04-15 15:19   ` [PATCH v3 09/24] n_tty: Don't wrap input buffer indices at buffer size Peter Hurley
2013-04-15 15:19   ` [PATCH v3 10/24] n_tty: Remove read_cnt Peter Hurley
2013-04-15 15:19   ` [PATCH v3 11/24] tty: Convert termios_mutex to termios_rwsem Peter Hurley
2013-04-15 15:19   ` [PATCH v3 12/24] n_tty: Access termios values safely Peter Hurley
2013-04-15 15:19   ` [PATCH v3 13/24] n_tty: Replace canon_data with index comparison Peter Hurley
2013-04-15 15:19   ` [PATCH v3 14/24] n_tty: Make N_TTY ldisc receive path lockless Peter Hurley
2013-04-15 15:19   ` [PATCH v3 15/24] n_tty: Reset lnext if canonical mode changes Peter Hurley
2013-04-15 15:19   ` [PATCH v3 16/24] n_tty: Fix type mismatches in receive_buf raw copy Peter Hurley
2013-04-15 15:19   ` [PATCH v3 17/24] n_tty: Don't wait for buffer work in read() loop Peter Hurley
2013-04-15 15:19   ` [PATCH v3 18/24] n_tty: Separate buffer indices to prevent cache-line sharing Peter Hurley
2013-04-15 15:19   ` [PATCH v3 19/24] tty: Only guarantee termios read safety for throttle/unthrottle Peter Hurley
2013-04-15 15:19   ` [PATCH v3 20/24] n_tty: Move chars_in_buffer() to factor throttle/unthrottle Peter Hurley
2013-04-15 15:19   ` [PATCH v3 21/24] n_tty: Factor throttle/unthrottle into helper functions Peter Hurley
2013-04-15 15:19   ` [PATCH v3 22/24] n_tty: Move n_tty_write_wakeup() to avoid forward declaration Peter Hurley
2013-04-15 15:19   ` [PATCH v3 23/24] n_tty: Special case pty flow control Peter Hurley
2013-04-15 15:19   ` [PATCH v3 24/24] n_tty: Queue buffer work on any available cpu Peter Hurley
2013-04-15 15:25   ` [PATCH 00/16] lockless tty flip buffers Peter Hurley
2013-04-15 15:25     ` [PATCH 01/16] tty: Compute flip buffer ptrs Peter Hurley
2013-04-15 15:25     ` [PATCH 02/16] tty: Fix flip buffer free list Peter Hurley
2013-04-15 15:25     ` [PATCH 03/16] tty: Factor flip buffer initialization into helper function Peter Hurley
2013-04-15 15:25     ` [PATCH 04/16] tty: Merge tty_buffer_find() into tty_buffer_alloc() Peter Hurley
2013-04-15 15:25     ` [PATCH 05/16] tty: Use generic names for flip buffer list cursors Peter Hurley
2013-04-15 15:25     ` [PATCH 06/16] tty: Use lockless flip buffer free list Peter Hurley
2013-04-15 15:25     ` [PATCH 07/16] tty: Simplify flip buffer list with 0-sized sentinel Peter Hurley
2013-04-15 15:25     ` [PATCH 08/16] tty: Track flip buffer memory limit atomically Peter Hurley
2013-04-15 15:26     ` [PATCH 09/16] tty: Make driver-side flip buffers lockless Peter Hurley
2013-04-15 15:26     ` [PATCH 10/16] tty: Ensure single-threaded flip buffer consumer with mutex Peter Hurley
2013-04-15 15:26     ` [PATCH 11/16] tty: Only perform flip buffer flush from tty_buffer_flush() Peter Hurley
2013-04-15 15:26     ` [PATCH 12/16] tty: Avoid false-sharing flip buffer ptrs Peter Hurley
2013-04-15 15:26     ` [PATCH 13/16] tty: Use non-atomic state to signal flip buffer flush pending Peter Hurley
2013-04-15 15:26     ` [PATCH 14/16] tty: Merge __tty_flush_buffer() into lone call site Peter Hurley
2013-04-15 15:26     ` [PATCH 15/16] tty: Fix unsafe vt paste_selection() Peter Hurley
2013-04-15 15:26     ` [PATCH 16/16] tty: Remove private constant from global namespace Peter Hurley
2013-04-15 15:29     ` [PATCH 0/9] mostly lockless tty echo Peter Hurley
2013-04-15 15:29       ` [PATCH 1/9] n_tty: Remove unused echo_overrun field Peter Hurley
2013-04-15 15:29       ` [PATCH 2/9] n_tty: Use separate head and tail indices for echo_buf Peter Hurley
2013-04-15 15:29       ` [PATCH 3/9] n_tty: Replace echo_cnt with computed value Peter Hurley
2013-04-15 15:29       ` [PATCH 4/9] n_tty: Remove echo_lock Peter Hurley
2013-04-15 15:29       ` [PATCH 5/9] n_tty: Eliminate echo_commit memory barrier Peter Hurley
2013-04-15 15:29       ` [PATCH 6/9] n_tty: Process echoes in blocks Peter Hurley
2013-04-15 15:29       ` [PATCH 7/9] n_tty: Only flush echo output if actually output Peter Hurley
2013-04-15 15:29       ` [PATCH 8/9] n_tty: Eliminate counter in __process_echoes Peter Hurley
2013-04-15 15:29       ` [PATCH 9/9] n_tty: Avoid false-sharing echo buffer indices Peter Hurley
2013-04-15 15:32       ` [PATCH 00/20] streamline per-char receiving Peter Hurley
2013-04-15 15:32         ` [PATCH 01/20] n_tty: Fix EOF push handling Peter Hurley
2013-04-15 15:32         ` [PATCH 02/20] n_tty: Remove alias ptrs in __receive_buf() Peter Hurley
2013-04-15 15:32         ` [PATCH 03/20] n_tty: Move buffers into n_tty_data Peter Hurley
2013-04-15 15:32         ` [PATCH 04/20] n_tty: Rename process_char_map to char_map Peter Hurley
2013-04-15 15:32         ` [PATCH 05/20] n_tty: Simplify __receive_buf loop count Peter Hurley
2013-04-15 15:32         ` [PATCH 06/20] n_tty: Factor 'real raw' receive_buf into standalone fn Peter Hurley
2013-04-15 15:32         ` [PATCH 07/20] n_tty: Factor signal char handling into separate fn Peter Hurley
2013-04-15 15:32         ` [PATCH 08/20] n_tty: Factor flagged " Peter Hurley
2013-04-15 15:32         ` [PATCH 09/20] n_tty: Factor raw mode receive_buf() " Peter Hurley
2013-04-15 15:32         ` [PATCH 10/20] n_tty: Special case EXTPROC receive_buf() as raw mode Peter Hurley
2013-04-15 15:32         ` [PATCH 11/20] n_tty: Factor tty->closing receive_buf() into separate fn Peter Hurley
2013-04-15 15:32         ` [PATCH 12/20] n_tty: Factor standard per-char i/o " Peter Hurley
2013-04-15 15:32         ` [PATCH 13/20] n_tty: Eliminate char tests from IXANY restart test Peter Hurley
2013-04-15 15:32         ` [PATCH 14/20] n_tty: Split n_tty_receive_char() Peter Hurley
2013-04-15 15:32         ` [PATCH 15/20] n_tty: Factor ISTRIP and IUCLC receive_buf into separate fn Peter Hurley
2013-04-15 15:32         ` [PATCH 16/20] n_tty: Factor PARMRK from normal per-char i/o Peter Hurley
2013-04-15 15:32         ` [PATCH 17/20] n_tty: Remove overflow tests from receive_buf() path Peter Hurley
2013-04-15 15:32         ` [PATCH 18/20] n_tty: Un-inline single-use functions Peter Hurley
2013-04-15 15:32         ` [PATCH 19/20] n_tty: Factor LNEXT processing from per-char i/o path Peter Hurley
2013-04-15 15:32         ` [PATCH 20/20] tty: Remove extra wakeup from pty write() path Peter Hurley
2013-04-15 20:14   ` [PATCH v3 00/24] lockless n_tty receive path Greg Kroah-Hartman
2013-04-16 10:15     ` [PATCH 1/7] tty: Add timed, writer-prioritized rw semaphore Peter Hurley
2013-04-16 10:15       ` [PATCH 2/7] tty: Add lock/unlock ldisc pair functions Peter Hurley
2013-05-20 19:34         ` Greg Kroah-Hartman
2013-05-20 21:44           ` Peter Hurley
2013-05-20 23:06             ` Greg Kroah-Hartman
2013-05-20 23:38               ` Peter Hurley
2013-06-03 19:24                 ` Greg Kroah-Hartman
2013-06-15 11:04                   ` [PATCH 0/6] ldsem patchset, reordered and rebased Peter Hurley
2013-06-15 11:04                     ` [PATCH 1/6] tty: Fix tty_ldisc_lock name collision Peter Hurley
2013-06-15 11:04                     ` [PATCH 2/6] tty: Add lock/unlock ldisc pair functions Peter Hurley
2013-06-15 11:04                     ` [PATCH 3/6] tty: Replace ldisc locking with ldisc_sem Peter Hurley
2013-06-15 11:04                     ` [PATCH 4/6] tty: Clarify ldisc variable Peter Hurley
2013-06-15 11:04                     ` [PATCH 5/6] tty: Fix hangup race with TIOCSETD ioctl Peter Hurley
2013-06-15 11:04                     ` [PATCH 6/6] tty: Clarify multiple-references comment in " Peter Hurley
2013-07-23 23:44                     ` [PATCH 0/6] ldsem patchset, reordered and rebased Greg Kroah-Hartman
2013-04-16 10:15       ` [PATCH 3/7] tty: Replace ldisc locking with ldisc_sem Peter Hurley
2013-04-16 10:15       ` [PATCH 4/7] tty: Clarify ldisc variable Peter Hurley
2013-04-16 10:15       ` [PATCH 5/7] tty: Fix hangup race with TIOCSETD ioctl Peter Hurley
2013-04-16 10:15       ` [PATCH 6/7] tty: Clarify multiple-references comment in " Peter Hurley
2013-04-16 10:15       ` [PATCH 7/7] tty: Fix tty_ldisc_lock name collision Peter Hurley
2013-06-15 13:14   ` [PATCH v4 00/24] lockless n_tty receive path Peter Hurley
2013-06-15 13:14     ` [PATCH v4 01/24] tty: Don't change receive_room for ioctl(TIOCSETD) Peter Hurley
2013-06-15 13:14     ` [PATCH v4 02/24] tty: Simplify tty buffer/ldisc interface with helper function Peter Hurley
2013-06-15 13:14     ` [PATCH v4 03/24] tty: Make ldisc input flow control concurrency-friendly Peter Hurley
2013-06-15 13:14     ` [PATCH v4 04/24] n_tty: Factor canonical mode copy from n_tty_read() Peter Hurley
2013-06-15 13:14     ` [PATCH v4 05/24] n_tty: Line copy to user buffer in canonical mode Peter Hurley
2013-06-15 13:14     ` [PATCH v4 06/24] n_tty: Split n_tty_chars_in_buffer() for reader-only interface Peter Hurley
2013-06-15 13:14     ` [PATCH v4 07/24] tty: Deprecate ldisc .chars_in_buffer() method Peter Hurley
2013-06-15 13:14     ` [PATCH v4 08/24] n_tty: Get read_cnt through accessor Peter Hurley
2013-06-15 13:14     ` [PATCH v4 09/24] n_tty: Don't wrap input buffer indices at buffer size Peter Hurley
2013-06-15 13:14     ` [PATCH v4 10/24] n_tty: Remove read_cnt Peter Hurley
2013-06-15 13:14     ` [PATCH v4 11/24] tty: Convert termios_mutex to termios_rwsem Peter Hurley
2013-06-15 13:14     ` [PATCH v4 12/24] n_tty: Access termios values safely Peter Hurley
2013-06-15 13:14     ` [PATCH v4 13/24] n_tty: Replace canon_data with index comparison Peter Hurley
2013-06-15 13:14     ` [PATCH v4 14/24] n_tty: Make N_TTY ldisc receive path lockless Peter Hurley
2013-06-15 13:14     ` [PATCH v4 15/24] n_tty: Reset lnext if canonical mode changes Peter Hurley
2013-06-15 13:14     ` [PATCH v4 16/24] n_tty: Fix type mismatches in receive_buf raw copy Peter Hurley
2013-06-15 13:14     ` [PATCH v4 17/24] n_tty: Don't wait for buffer work in read() loop Peter Hurley
2013-06-15 13:14     ` [PATCH v4 18/24] n_tty: Separate buffer indices to prevent cache-line sharing Peter Hurley
2013-06-15 13:14     ` [PATCH v4 19/24] tty: Only guarantee termios read safety for throttle/unthrottle Peter Hurley
2013-06-15 13:14     ` [PATCH v4 20/24] n_tty: Move chars_in_buffer() to factor throttle/unthrottle Peter Hurley
2013-06-15 13:14     ` [PATCH v4 21/24] n_tty: Factor throttle/unthrottle into helper functions Peter Hurley
2013-06-15 13:14     ` [PATCH v4 22/24] n_tty: Move n_tty_write_wakeup() to avoid forward declaration Peter Hurley
2013-06-15 13:14     ` [PATCH v4 23/24] n_tty: Special case pty flow control Peter Hurley
2013-07-23 12:47       ` [PATCH v5 " Peter Hurley
2013-06-15 13:14     ` [PATCH v4 24/24] n_tty: Queue buffer work on any available cpu Peter Hurley
2013-06-15 13:36     ` [PATCH v2 00/16] lockless tty flip buffers Peter Hurley
2013-06-15 13:36       ` [PATCH v2 01/16] tty: Compute flip buffer ptrs Peter Hurley
2013-06-15 13:36       ` [PATCH v2 02/16] tty: Fix flip buffer free list Peter Hurley
2013-06-15 13:36       ` [PATCH v2 03/16] tty: Factor flip buffer initialization into helper function Peter Hurley
2013-06-15 13:36       ` [PATCH v2 04/16] tty: Merge tty_buffer_find() into tty_buffer_alloc() Peter Hurley
2013-06-15 13:36       ` [PATCH v2 05/16] tty: Use generic names for flip buffer list cursors Peter Hurley
2013-06-15 13:36       ` [PATCH v2 06/16] tty: Use lockless flip buffer free list Peter Hurley
2013-06-15 13:36       ` [PATCH v2 07/16] tty: Simplify flip buffer list with 0-sized sentinel Peter Hurley
2013-06-15 13:36       ` [PATCH v2 08/16] tty: Track flip buffer memory limit atomically Peter Hurley
2013-06-15 13:36       ` [PATCH v2 09/16] tty: Make driver-side flip buffers lockless Peter Hurley
2013-06-15 13:36       ` [PATCH v2 10/16] tty: Ensure single-threaded flip buffer consumer with mutex Peter Hurley
2013-06-15 13:36       ` [PATCH v2 11/16] tty: Only perform flip buffer flush from tty_buffer_flush() Peter Hurley
2013-06-15 13:36       ` [PATCH v2 12/16] tty: Avoid false-sharing flip buffer ptrs Peter Hurley
2013-06-15 13:36       ` [PATCH v2 13/16] tty: Use non-atomic state to signal flip buffer flush pending Peter Hurley
2013-06-15 13:36       ` [PATCH v2 14/16] tty: Merge __tty_flush_buffer() into lone call site Peter Hurley
2013-06-15 13:36       ` [PATCH v2 15/16] tty: Fix unsafe vt paste_selection() Peter Hurley
2013-06-15 13:36       ` [PATCH v2 16/16] tty: Remove private constant from global namespace Peter Hurley
2013-06-15 14:04       ` [PATCH v2 0/9] mostly lockless tty echo Peter Hurley
2013-06-15 14:04         ` [PATCH v2 1/9] n_tty: Remove unused echo_overrun field Peter Hurley
2013-06-15 14:04         ` [PATCH v2 2/9] n_tty: Use separate head and tail indices for echo_buf Peter Hurley
2013-06-15 14:04         ` [PATCH v2 3/9] n_tty: Replace echo_cnt with computed value Peter Hurley
2013-06-15 14:04         ` [PATCH v2 4/9] n_tty: Remove echo_lock Peter Hurley
2013-06-15 14:04         ` [PATCH v2 5/9] n_tty: Eliminate echo_commit memory barrier Peter Hurley
2013-06-15 14:04         ` [PATCH v2 6/9] n_tty: Process echoes in blocks Peter Hurley
2013-07-23 23:53           ` Greg Kroah-Hartman
2013-07-25  1:33             ` Peter Hurley
2013-06-15 14:04         ` [PATCH v2 7/9] n_tty: Only flush echo output if actually output Peter Hurley
2013-06-15 14:04         ` [PATCH v2 8/9] n_tty: Eliminate counter in __process_echoes Peter Hurley
2013-06-15 14:04         ` [PATCH v2 9/9] n_tty: Avoid false-sharing echo buffer indices Peter Hurley
2013-06-15 14:21         ` [PATCH v2 00/20] tty: streamline per-char receiving Peter Hurley
2013-06-15 14:21           ` [PATCH v2 01/20] n_tty: Fix EOF push handling Peter Hurley
2013-06-15 14:21           ` [PATCH v2 02/20] n_tty: Remove alias ptrs in __receive_buf() Peter Hurley
2013-06-15 14:21           ` [PATCH v2 03/20] n_tty: Move buffers into n_tty_data Peter Hurley
2013-06-15 14:21           ` [PATCH v2 04/20] n_tty: Rename process_char_map to char_map Peter Hurley
2013-06-15 14:21           ` [PATCH v2 05/20] n_tty: Simplify __receive_buf loop count Peter Hurley
2013-06-15 14:21           ` [PATCH v2 06/20] n_tty: Factor 'real raw' receive_buf into standalone fn Peter Hurley
2013-06-15 14:21           ` [PATCH v2 07/20] n_tty: Factor signal char handling into separate fn Peter Hurley
2013-06-15 14:21           ` [PATCH v2 08/20] n_tty: Factor flagged " Peter Hurley
2013-06-15 14:21           ` [PATCH v2 09/20] n_tty: Factor raw mode receive_buf() " Peter Hurley
2013-06-15 14:21           ` [PATCH v2 10/20] n_tty: Special case EXTPROC receive_buf() as raw mode Peter Hurley
2013-06-15 14:21           ` [PATCH v2 11/20] n_tty: Factor tty->closing receive_buf() into separate fn Peter Hurley
2013-06-15 14:21           ` [PATCH v2 12/20] n_tty: Factor standard per-char i/o " Peter Hurley
2013-07-24  0:12             ` Greg Kroah-Hartman
2013-07-24  0:12               ` Greg Kroah-Hartman
2013-07-24  0:49               ` Peter Hurley
2013-07-24  0:49                 ` Peter Hurley
2013-07-24 12:29               ` [PATCH v3 1/9] " Peter Hurley
2013-07-24 12:29                 ` [PATCH v3 2/9] n_tty: Eliminate char tests from IXANY restart test Peter Hurley
2013-07-24 12:29                 ` [PATCH v3 3/9] n_tty: Split n_tty_receive_char() Peter Hurley
2013-07-24 12:29                 ` [PATCH v3 4/9] n_tty: Factor ISTRIP and IUCLC receive_buf into separate fn Peter Hurley
2013-07-24 12:29                 ` [PATCH v3 5/9] n_tty: Factor PARMRK from normal per-char i/o Peter Hurley
2013-07-24 12:29                 ` [PATCH v3 6/9] n_tty: Remove overflow tests from receive_buf() path Peter Hurley
2013-07-24 12:29                 ` [PATCH v3 7/9] n_tty: Un-inline single-use functions Peter Hurley
2013-07-24 12:29                 ` [PATCH v3 8/9] n_tty: Factor LNEXT processing from per-char i/o path Peter Hurley
2013-07-24 12:29                 ` [PATCH v3 9/9] tty: Remove extra wakeup from pty write() path Peter Hurley
2013-06-15 14:21           ` [PATCH v2 13/20] n_tty: Eliminate char tests from IXANY restart test Peter Hurley
2013-06-15 14:21           ` [PATCH v2 14/20] n_tty: Split n_tty_receive_char() Peter Hurley
2013-06-15 14:21           ` [PATCH v2 15/20] n_tty: Factor ISTRIP and IUCLC receive_buf into separate fn Peter Hurley
2013-06-15 14:21           ` [PATCH v2 16/20] n_tty: Factor PARMRK from normal per-char i/o Peter Hurley
2013-06-15 14:21           ` [PATCH v2 17/20] n_tty: Remove overflow tests from receive_buf() path Peter Hurley
2013-06-15 14:21           ` [PATCH v2 18/20] n_tty: Un-inline single-use functions Peter Hurley
2013-06-15 14:21           ` [PATCH v2 19/20] n_tty: Factor LNEXT processing from per-char i/o path Peter Hurley
2013-06-15 14:21           ` [PATCH v2 20/20] tty: Remove extra wakeup from pty write() path Peter Hurley
2013-07-20 17:00             ` Peter Hurley
2013-07-23 12:57               ` Peter Hurley
2013-07-23 15:02                 ` Greg Kroah-Hartman
2013-07-24  0:04         ` [PATCH v2 0/9] mostly lockless tty echo Greg Kroah-Hartman
2013-07-23 23:53       ` [PATCH v2 00/16] lockless tty flip buffers Greg Kroah-Hartman
2013-06-17 20:01     ` [PATCH v4 00/24] lockless n_tty receive path Greg Kroah-Hartman
2013-06-17 20:32       ` Peter Hurley
2013-07-23 23:44         ` Greg Kroah-Hartman

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=1363724513-15604-15-git-send-email-peter@hurleysoftware.com \
    --to=peter@hurleysoftware.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=jslaby@suse.cz \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-serial@vger.kernel.org \
    --cc=mzhang@mvista.com \
    /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.