summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/tty_ioctl.c13
-rw-r--r--include/linux/tty_driver.h6
2 files changed, 17 insertions, 2 deletions
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index 6f4c7d0a53bf..2401dbcbee9c 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -97,14 +97,19 @@ EXPORT_SYMBOL(tty_driver_flush_buffer);
* @tty: terminal
*
* Indicate that a tty should stop transmitting data down the stack.
+ * Takes the termios mutex to protect against parallel throttle/unthrottle
+ * and also to ensure the driver can consistently reference its own
+ * termios data at this point when implementing software flow control.
*/
void tty_throttle(struct tty_struct *tty)
{
+ mutex_lock(&tty->termios_mutex);
/* check TTY_THROTTLED first so it indicates our state */
if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) &&
tty->ops->throttle)
tty->ops->throttle(tty);
+ mutex_unlock(&tty->termios_mutex);
}
EXPORT_SYMBOL(tty_throttle);
@@ -113,13 +118,21 @@ EXPORT_SYMBOL(tty_throttle);
* @tty: terminal
*
* Indicate that a tty may continue transmitting data down the stack.
+ * Takes the termios mutex to protect against parallel throttle/unthrottle
+ * and also to ensure the driver can consistently reference its own
+ * termios data at this point when implementing software flow control.
+ *
+ * Drivers should however remember that the stack can issue a throttle,
+ * then change flow control method, then unthrottle.
*/
void tty_unthrottle(struct tty_struct *tty)
{
+ mutex_lock(&tty->termios_mutex);
if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) &&
tty->ops->unthrottle)
tty->ops->unthrottle(tty);
+ mutex_unlock(&tty->termios_mutex);
}
EXPORT_SYMBOL(tty_unthrottle);
diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h
index bcba84ea2d86..3566129384a4 100644
--- a/include/linux/tty_driver.h
+++ b/include/linux/tty_driver.h
@@ -127,7 +127,8 @@
* the line discipline are close to full, and it should somehow
* signal that no more characters should be sent to the tty.
*
- * Optional: Always invoke via tty_throttle();
+ * Optional: Always invoke via tty_throttle(), called under the
+ * termios lock.
*
* void (*unthrottle)(struct tty_struct * tty);
*
@@ -135,7 +136,8 @@
* that characters can now be sent to the tty without fear of
* overrunning the input buffers of the line disciplines.
*
- * Optional: Always invoke via tty_unthrottle();
+ * Optional: Always invoke via tty_unthrottle(), called under the
+ * termios lock.
*
* void (*stop)(struct tty_struct *tty);
*