• Paolo Valente's avatar
    block, bfq: preempt lower-weight or lower-priority queues · 96a291c3
    Paolo Valente authored
    BFQ enqueues the I/O coming from each process into a separate
    bfq_queue, and serves bfq_queues one at a time. Each bfq_queue may be
    served for at most timeout_sync milliseconds (default: 125 ms). This
    service scheme is prone to the following inaccuracy.
    
    While a bfq_queue Q1 is in service, some empty bfq_queue Q2 may
    receive I/O, and, according to BFQ's scheduling policy, may become the
    right bfq_queue to serve, in place of the currently in-service
    bfq_queue. In this respect, postponing the service of Q2 to after the
    service of Q1 finishes may delay the completion of Q2's I/O, compared
    with an ideal service in which all non-empty bfq_queues are served in
    parallel, and every non-empty bfq_queue is served at a rate
    proportional to the bfq_queue's weight. This additional delay is equal
    at most to the time Q1 may unjustly remain in service before switching
    to Q2.
    
    If Q1 and Q2 have the same weight, then this time is most likely
    negligible compared with the completion time to be guaranteed to Q2's
    I/O. In addition, first, one of the reasons why BFQ may want to serve
    Q1 for a while is that this boosts throughput and, second, serving Q1
    longer reduces BFQ's overhead. As a conclusion, it is usually better
    not to preempt Q1 if both Q1 and Q2 have the same weight.
    
    In contrast, as Q2's weight or priority becomes higher and higher
    compared with that of Q1, the above delay becomes larger and larger,
    compared with the I/O completion times that have to be guaranteed to
    Q2 according to Q2's weight. So reducing this delay may be more
    important than avoiding the costs of preempting Q1.
    
    Accordingly, this commit preempts Q1 if Q2 has a higher weight or a
    higher priority than Q1. Preemption causes Q1 to be re-scheduled, and
    triggers a new choice of the next bfq_queue to serve. If Q2 really is
    the next bfq_queue to serve, then Q2 will be set in service
    immediately.
    
    This change reduces the component of the I/O latency caused by the
    above delay by about 80%. For example, on an (old) PLEXTOR PX-256M5
    SSD, the maximum latency reported by fio drops from 15.1 to 3.2 ms for
    a process doing sporadic random reads while another process is doing
    continuous sequential reads.
    Signed-off-by: default avatarNicola Bottura <bottura.nicola95@gmail.com>
    Signed-off-by: default avatarPaolo Valente <paolo.valente@linaro.org>
    Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
    96a291c3
bfq-iosched.c 231 KB