diff options
author | Peter Hurley <peter@hurleysoftware.com> | 2013-06-15 15:14:31 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-07-24 01:43:02 +0200 |
commit | d8c1f929aa8164cd8eaa830068d2fa3159c0764a (patch) | |
tree | 1371cfe90fffdcb7115b39c77e0f729c109efc69 | |
parent | n_tty: Separate buffer indices to prevent cache-line sharing (diff) | |
download | linux-d8c1f929aa8164cd8eaa830068d2fa3159c0764a.tar.xz linux-d8c1f929aa8164cd8eaa830068d2fa3159c0764a.zip |
tty: Only guarantee termios read safety for throttle/unthrottle
No tty driver modifies termios during throttle() or unthrottle().
Therefore, only read safety is required.
However, tty_throttle_safe and tty_unthrottle_safe must still be
mutually exclusive; introduce throttle_mutex for that purpose.
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/tty/n_tty.c | 4 | ||||
-rw-r--r-- | drivers/tty/tty_io.c | 1 | ||||
-rw-r--r-- | drivers/tty/tty_ioctl.c | 8 | ||||
-rw-r--r-- | include/linux/tty.h | 1 |
4 files changed, 6 insertions, 8 deletions
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index d0c8805d8131..b78ee464bd09 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1518,9 +1518,7 @@ static void __receive_buf(struct tty_struct *tty, const unsigned char *cp, tty_set_flow_change(tty, TTY_THROTTLE_SAFE); if (receive_room(tty) >= TTY_THRESHOLD_THROTTLE) break; - up_read(&tty->termios_rwsem); throttled = tty_throttle_safe(tty); - down_read(&tty->termios_rwsem); if (!throttled) break; } @@ -2086,9 +2084,7 @@ do_it_again: if (!tty->count) break; n_tty_set_room(tty); - up_read(&tty->termios_rwsem); unthrottled = tty_unthrottle_safe(tty); - down_read(&tty->termios_rwsem); if (!unthrottled) break; } diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 639e24ade9bf..1b32da6f6cdd 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -3015,6 +3015,7 @@ void initialize_tty_struct(struct tty_struct *tty, tty->session = NULL; tty->pgrp = NULL; mutex_init(&tty->legacy_mutex); + mutex_init(&tty->throttle_mutex); init_rwsem(&tty->termios_rwsem); init_ldsem(&tty->ldisc_sem); init_waitqueue_head(&tty->write_wait); diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index 9ce20df8a2c8..03ba081c5772 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c @@ -151,7 +151,7 @@ int tty_throttle_safe(struct tty_struct *tty) { int ret = 0; - down_write(&tty->termios_rwsem); + mutex_lock(&tty->throttle_mutex); if (!test_bit(TTY_THROTTLED, &tty->flags)) { if (tty->flow_change != TTY_THROTTLE_SAFE) ret = 1; @@ -161,7 +161,7 @@ int tty_throttle_safe(struct tty_struct *tty) tty->ops->throttle(tty); } } - up_write(&tty->termios_rwsem); + mutex_unlock(&tty->throttle_mutex); return ret; } @@ -182,7 +182,7 @@ int tty_unthrottle_safe(struct tty_struct *tty) { int ret = 0; - down_write(&tty->termios_rwsem); + mutex_lock(&tty->throttle_mutex); if (test_bit(TTY_THROTTLED, &tty->flags)) { if (tty->flow_change != TTY_UNTHROTTLE_SAFE) ret = 1; @@ -192,7 +192,7 @@ int tty_unthrottle_safe(struct tty_struct *tty) tty->ops->unthrottle(tty); } } - up_write(&tty->termios_rwsem); + mutex_unlock(&tty->throttle_mutex); return ret; } diff --git a/include/linux/tty.h b/include/linux/tty.h index d3042076d163..57a70d1d0412 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -244,6 +244,7 @@ struct tty_struct { struct mutex atomic_write_lock; struct mutex legacy_mutex; + struct mutex throttle_mutex; struct rw_semaphore termios_rwsem; spinlock_t ctrl_lock; /* Termios values are protected by the termios rwsem */ |