[PATCH 2/7] n_tty: fix throttling

From: Alan Cox
Date: Wed Nov 18 2009 - 09:26:53 EST


n_tty inadevertently calls throttle and unthrottle methods during its init.
This happens before the tty device is open and causes problems for the
drivers, in particular they may not have their state and locks even
initialised at this point.

Signed-off-by: Alan Cox <alan@xxxxxxxxxxxxxxx>
---

drivers/char/n_tty.c | 35 ++++++++++++++++++++++++++---------
1 files changed, 26 insertions(+), 9 deletions(-)


diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index 2e50f4d..b45170c 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -178,26 +178,23 @@ static void reset_buffer_flags(struct tty_struct *tty)
tty->canon_head = tty->canon_data = tty->erasing = 0;
memset(&tty->read_flags, 0, sizeof tty->read_flags);
n_tty_set_room(tty);
- check_unthrottle(tty);
}

/**
- * n_tty_flush_buffer - clean input queue
+ * n_tty_do_flush - clean input queue
* @tty: terminal device
*
* Flush the input buffer. Called when the line discipline is
- * being closed, when the tty layer wants the buffer flushed (eg
- * at hangup) or when the N_TTY line discipline internally has to
- * clean the pending queue (for example some signals).
+ * being closed, or indirectly when the tty layer wants the 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.
*/

-static void n_tty_flush_buffer(struct tty_struct *tty)
+static void n_tty_do_flush(struct tty_struct *tty)
{
unsigned long flags;
- /* clear everything and unthrottle the driver */
- reset_buffer_flags(tty);

if (!tty->link)
return;
@@ -211,6 +208,25 @@ static void n_tty_flush_buffer(struct tty_struct *tty)
}

/**
+ * n_tty_flush_buffer - clean input queue
+ * @tty: terminal device
+ *
+ * Flush the input buffer. Called when the tty layer wants the 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.
+ */
+
+static void n_tty_flush_buffer(struct tty_struct *tty)
+{
+ /* clear everything and unthrottle the driver */
+ reset_buffer_flags(tty);
+ check_unthrottle(tty);
+ n_tty_do_flush(tty);
+}
+
+/**
* n_tty_chars_in_buffer - report available bytes
* @tty: tty device
*
@@ -1535,7 +1551,8 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)

static void n_tty_close(struct tty_struct *tty)
{
- n_tty_flush_buffer(tty);
+ reset_buffer_flags(tty);
+ n_tty_do_flush(tty);
if (tty->read_buf) {
kfree(tty->read_buf);
tty->read_buf = NULL;

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/