• Paolo Valente's avatar
    block, bfq: fix wrong init of saved start time for weight raising · 1a2d9921
    Paolo Valente authored
    commit 4baa8bb13f41307f3eb62fe91f93a1a798ebef53 upstream.
    This commit fixes a bug that causes bfq to fail to guarantee a high
    responsiveness on some drives, if there is heavy random read+write I/O
    in the background. More precisely, such a failure allowed this bug to
    be found [1], but the bug may well cause other yet unreported
    BFQ raises the weight of the bfq_queues associated with soft real-time
    applications, to privilege the I/O, and thus reduce latency, for these
    applications. This mechanism is named soft-real-time weight raising in
    BFQ. A soft real-time period may happen to be nested into an
    interactive weight raising period, i.e., it may happen that, when a
    bfq_queue switches to a soft real-time weight-raised state, the
    bfq_queue is already being weight-raised because deemed interactive
    too. In this case, BFQ saves in a special variable
    wr_start_at_switch_to_srt, the time instant when the interactive
    weight-raising period started for the bfq_queue, i.e., the time
    instant when BFQ started to deem the bfq_queue interactive. This value
    is then used to check whether the interactive weight-raising period
    would still be in progress when the soft real-time weight-raising
    period ends.  If so, interactive weight raising is restored for the
    bfq_queue. This restore is useful, in particular, because it prevents
    bfq_queues from losing their interactive weight raising prematurely,
    as a consequence of spurious, short-lived soft real-time
    weight-raising periods caused by wrong detections as soft real-time.
    If, instead, a bfq_queue switches to soft-real-time weight raising
    while it *is not* already in an interactive weight-raising period,
    then the variable wr_start_at_switch_to_srt has no meaning during the
    following soft real-time weight-raising period. Unfortunately the
    handling of this case is wrong in BFQ: not only the variable is not
    flagged somehow as meaningless, but it is also set to the time when
    the switch to soft real-time weight-raising occurs. This may cause an
    interactive weight-raising period to be considered mistakenly as still
    in progress, and thus a spurious interactive weight-raising period to
    start for the bfq_queue, at the end of the soft-real-time
    weight-raising period. In particular the spurious interactive
    weight-raising period will be considered as still in progress, if the
    soft-real-time weight-raising period does not last very long. The
    bfq_queue will then be wrongly privileged and, if I/O bound, will
    unjustly steal bandwidth to truly interactive or soft real-time
    bfq_queues, harming responsiveness and low latency.
    This commit fixes this issue by just setting wr_start_at_switch_to_srt
    to minus infinity (farthest past time instant according to jiffies
    macros): when the soft-real-time weight-raising period ends, certainly
    no interactive weight-raising period will be considered as still in
    [1] Background I/O Type: Random - Background I/O mix: Reads and writes
    - Application to start: LibreOffice Writer in
    http://www.phoronix.com/scan.php?page=news_item&px=Linux-4.13-IO-LaptopSigned-off-by: 's avatarPaolo Valente <paolo.valente@linaro.org>
    Signed-off-by: 's avatarAngelo Ruocco <angeloruocco90@gmail.com>
    Tested-by: 's avatarOleksandr Natalenko <oleksandr@natalenko.name>
    Tested-by: 's avatarLee Tibbert <lee.tibbert@gmail.com>
    Tested-by: 's avatarMirko Montanari <mirkomontanari91@gmail.com>
    Signed-off-by: 's avatarJens Axboe <axboe@kernel.dk>
    Signed-off-by: 's avatarSudip Mukherjee <sudipm.mukherjee@gmail.com>
    Signed-off-by: 's avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>