aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/tty/n_tty.c4
-rw-r--r--drivers/tty/tty_io.c1
-rw-r--r--drivers/tty/tty_ioctl.c8
-rw-r--r--include/linux/tty.h1
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,
1518 tty_set_flow_change(tty, TTY_THROTTLE_SAFE); 1518 tty_set_flow_change(tty, TTY_THROTTLE_SAFE);
1519 if (receive_room(tty) >= TTY_THRESHOLD_THROTTLE) 1519 if (receive_room(tty) >= TTY_THRESHOLD_THROTTLE)
1520 break; 1520 break;
1521 up_read(&tty->termios_rwsem);
1522 throttled = tty_throttle_safe(tty); 1521 throttled = tty_throttle_safe(tty);
1523 down_read(&tty->termios_rwsem);
1524 if (!throttled) 1522 if (!throttled)
1525 break; 1523 break;
1526 } 1524 }
@@ -2086,9 +2084,7 @@ do_it_again:
2086 if (!tty->count) 2084 if (!tty->count)
2087 break; 2085 break;
2088 n_tty_set_room(tty); 2086 n_tty_set_room(tty);
2089 up_read(&tty->termios_rwsem);
2090 unthrottled = tty_unthrottle_safe(tty); 2087 unthrottled = tty_unthrottle_safe(tty);
2091 down_read(&tty->termios_rwsem);
2092 if (!unthrottled) 2088 if (!unthrottled)
2093 break; 2089 break;
2094 } 2090 }
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,
3015 tty->session = NULL; 3015 tty->session = NULL;
3016 tty->pgrp = NULL; 3016 tty->pgrp = NULL;
3017 mutex_init(&tty->legacy_mutex); 3017 mutex_init(&tty->legacy_mutex);
3018 mutex_init(&tty->throttle_mutex);
3018 init_rwsem(&tty->termios_rwsem); 3019 init_rwsem(&tty->termios_rwsem);
3019 init_ldsem(&tty->ldisc_sem); 3020 init_ldsem(&tty->ldisc_sem);
3020 init_waitqueue_head(&tty->write_wait); 3021 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)
151{ 151{
152 int ret = 0; 152 int ret = 0;
153 153
154 down_write(&tty->termios_rwsem); 154 mutex_lock(&tty->throttle_mutex);
155 if (!test_bit(TTY_THROTTLED, &tty->flags)) { 155 if (!test_bit(TTY_THROTTLED, &tty->flags)) {
156 if (tty->flow_change != TTY_THROTTLE_SAFE) 156 if (tty->flow_change != TTY_THROTTLE_SAFE)
157 ret = 1; 157 ret = 1;
@@ -161,7 +161,7 @@ int tty_throttle_safe(struct tty_struct *tty)
161 tty->ops->throttle(tty); 161 tty->ops->throttle(tty);
162 } 162 }
163 } 163 }
164 up_write(&tty->termios_rwsem); 164 mutex_unlock(&tty->throttle_mutex);
165 165
166 return ret; 166 return ret;
167} 167}
@@ -182,7 +182,7 @@ int tty_unthrottle_safe(struct tty_struct *tty)
182{ 182{
183 int ret = 0; 183 int ret = 0;
184 184
185 down_write(&tty->termios_rwsem); 185 mutex_lock(&tty->throttle_mutex);
186 if (test_bit(TTY_THROTTLED, &tty->flags)) { 186 if (test_bit(TTY_THROTTLED, &tty->flags)) {
187 if (tty->flow_change != TTY_UNTHROTTLE_SAFE) 187 if (tty->flow_change != TTY_UNTHROTTLE_SAFE)
188 ret = 1; 188 ret = 1;
@@ -192,7 +192,7 @@ int tty_unthrottle_safe(struct tty_struct *tty)
192 tty->ops->unthrottle(tty); 192 tty->ops->unthrottle(tty);
193 } 193 }
194 } 194 }
195 up_write(&tty->termios_rwsem); 195 mutex_unlock(&tty->throttle_mutex);
196 196
197 return ret; 197 return ret;
198} 198}
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 {
244 244
245 struct mutex atomic_write_lock; 245 struct mutex atomic_write_lock;
246 struct mutex legacy_mutex; 246 struct mutex legacy_mutex;
247 struct mutex throttle_mutex;
247 struct rw_semaphore termios_rwsem; 248 struct rw_semaphore termios_rwsem;
248 spinlock_t ctrl_lock; 249 spinlock_t ctrl_lock;
249 /* Termios values are protected by the termios rwsem */ 250 /* Termios values are protected by the termios rwsem */