• Peter Hurley's avatar
    tty: Add safe tty throttle/unthrottle functions · 70bc1264
    Peter Hurley authored
    The tty driver can become stuck throttled due to race conditions
    between throttle and unthrottle, when the decision to throttle
    or unthrottle is conditional. The following example helps to
    illustrate the race:
    
      CPU 0                        |  CPU 1
                                   |
    if (condition A)               |
                                   | <processing such that A not true>
                                   | if (!condition A)
                                   |     unthrottle()
        throttle()                 |
                                   |
    
    Note the converse is also possible; ie.,
    
      CPU 0                        |  CPU 1
                                   |
                                   | if (!condition A)
    <processing such that A true>  |
    if (condition A)               |
        throttle()                 |
                                   |     unthrottle()
                                   |
    
    Add new throttle/unthrottle functions based on the familiar model
    of task state and schedule/wake. For example,
    
        while (1) {
            tty_set_flow_change(tty, TTY_THROTTLE_SAFE);
            if (!condition)
                break;
            if (!tty_throttle_safe(tty))
                break;
        }
        __tty_set_flow_change(tty, 0);
    
    In this example, if an unthrottle occurs after the condition is
    evaluated but before tty_throttle_safe(), then tty_throttle_safe()
    will return non-zero, looping and forcing the re-evaluation of
    condition.
    Reported-by: default avatarVincent Pillet <vincentx.pillet@intel.com>
    Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    70bc1264
tty_ioctl.c 31.8 KB