• Paolo Valente's avatar
    block, bfq: check also in-flight I/O in dispatch plugging · b5e02b48
    Paolo Valente authored
    Consider a sync bfq_queue Q that remains empty while in service, and
    suppose that, when this happens, there is a fair amount of already
    in-flight I/O not belonging to Q. In such a situation, I/O dispatching
    may need to be plugged (until new I/O arrives for Q), for the
    following reason.
    
    The drive may decide to serve in-flight non-Q's I/O requests before
    Q's ones, thereby delaying the arrival of new I/O requests for Q
    (recall that Q is sync). If I/O-dispatching is not plugged, then,
    while Q remains empty, a basically uncontrolled amount of I/O from
    other queues may be dispatched too, possibly causing the service of
    Q's I/O to be delayed even longer in the drive. This problem gets more
    and more serious as the speed and the queue depth of the drive grow,
    because, as these two quantities grow, the probability to find no
    queue busy but many requests in flight grows too.
    
    If Q has the same weight and priority as the other queues, then the
    above delay is unlikely to cause any issue, because all queues tend to
    undergo the same treatment. So, since not plugging I/O dispatching is
    convenient for throughput, it is better not to plug. Things change in
    case Q has a higher weight or priority than some other queue, because
    Q's service guarantees may simply be violated. For this reason,
    commit 1de0c4cd ("block, bfq: reduce idling only in symmetric
    scenarios") does plug I/O in such an asymmetric scenario. Plugging
    minimizes the delay induced by already in-flight I/O, and enables Q to
    recover the bandwidth it may lose because of this delay.
    
    Yet the above commit does not cover the case of weight-raised queues,
    for efficiency concerns. For weight-raised queues, I/O-dispatch
    plugging is activated simply if not all bfq_queues are
    weight-raised. But this check does not handle the case of in-flight
    requests, because a bfq_queue may become non busy *before* all its
    in-flight requests are completed.
    
    This commit performs I/O-dispatch plugging for weight-raised queues if
    there are some in-flight requests.
    
    As a practical example of the resulting recover of control, under
    write load on a Samsung SSD 970 PRO, gnome-terminal starts in 1.5
    seconds after this fix, against 15 seconds before the fix (as a
    reference, gnome-terminal takes about 35 seconds to start with any of
    the other I/O schedulers).
    
    Fixes: 1de0c4cd ("block, bfq: reduce idling only in symmetric scenarios")
    Signed-off-by: default avatarPaolo Valente <paolo.valente@linaro.org>
    Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
    b5e02b48
bfq-iosched.c 234 KB