aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Hurley <peter@hurleysoftware.com>2013-03-06 08:20:53 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-03-18 19:11:59 -0400
commite91e52e42814b130c20d17bc1e2adf813c50db11 (patch)
tree3459953655d71ed43cedd3ecdc9fe637b7960bd0
parent70bc126471af30bb115e635512dcf6d86fe6e29a (diff)
n_tty: Fix stuck throttled driver
As noted in the following comment: /* FIXME: there is a tiny race here if the receive room check runs before the other work executes and empties the buffer (upping the receiving room and unthrottling. We then throttle and get stuck. This has been observed and traced down by Vincent Pillet/ We need to address this when we sort out out the rx path locking */ Use new safe throttle/unthrottle functions to re-evaluate conditions if interrupted by the complement flow control function. Reported-by: Vincent Pillet <vincentx.pillet@intel.com> Signed-off-by: Peter Hurley <peter@hurleysoftware.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/tty/n_tty.c28
1 files changed, 17 insertions, 11 deletions
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index 7fbad56db7c9..e3a9321f7f89 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -1468,14 +1468,14 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
1468 * mode. We don't want to throttle the driver if we're in 1468 * mode. We don't want to throttle the driver if we're in
1469 * canonical mode and don't have a newline yet! 1469 * canonical mode and don't have a newline yet!
1470 */ 1470 */
1471 if (tty->receive_room < TTY_THRESHOLD_THROTTLE) 1471 while (1) {
1472 tty_throttle(tty); 1472 tty_set_flow_change(tty, TTY_THROTTLE_SAFE);
1473 1473 if (tty->receive_room >= TTY_THRESHOLD_THROTTLE)
1474 /* FIXME: there is a tiny race here if the receive room check runs 1474 break;
1475 before the other work executes and empties the buffer (upping 1475 if (!tty_throttle_safe(tty))
1476 the receiving room and unthrottling. We then throttle and get 1476 break;
1477 stuck. This has been observed and traced down by Vincent Pillet/ 1477 }
1478 We need to address this when we sort out out the rx path locking */ 1478 __tty_set_flow_change(tty, 0);
1479} 1479}
1480 1480
1481int is_ignored(int sig) 1481int is_ignored(int sig)
@@ -1944,11 +1944,17 @@ do_it_again:
1944 * longer than TTY_THRESHOLD_UNTHROTTLE in canonical mode, 1944 * longer than TTY_THRESHOLD_UNTHROTTLE in canonical mode,
1945 * we won't get any more characters. 1945 * we won't get any more characters.
1946 */ 1946 */
1947 if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE) { 1947 while (1) {
1948 tty_set_flow_change(tty, TTY_UNTHROTTLE_SAFE);
1949 if (n_tty_chars_in_buffer(tty) > TTY_THRESHOLD_UNTHROTTLE)
1950 break;
1951 if (!tty->count)
1952 break;
1948 n_tty_set_room(tty); 1953 n_tty_set_room(tty);
1949 if (tty->count) 1954 if (!tty_unthrottle_safe(tty))
1950 tty_unthrottle(tty); 1955 break;
1951 } 1956 }
1957 __tty_set_flow_change(tty, 0);
1952 1958
1953 if (b - buf >= minimum) 1959 if (b - buf >= minimum)
1954 break; 1960 break;