• Paolo Valente's avatar
    block, bfq: add requeue-request hook · a7877390
    Paolo Valente authored
    Commit 'a6a252e6 ("blk-mq-sched: decide how to handle flush rq via
    RQF_FLUSH_SEQ")' makes all non-flush re-prepared requests for a device
    be re-inserted into the active I/O scheduler for that device. As a
    consequence, I/O schedulers may get the same request inserted again,
    even several times, without a finish_request invoked on that request
    before each re-insertion.
    
    This fact is the cause of the failure reported in [1]. For an I/O
    scheduler, every re-insertion of the same re-prepared request is
    equivalent to the insertion of a new request. For schedulers like
    mq-deadline or kyber, this fact causes no harm. In contrast, it
    confuses a stateful scheduler like BFQ, which keeps state for an I/O
    request, until the finish_request hook is invoked on the request. In
    particular, BFQ may get stuck, waiting forever for the number of
    request dispatches, of the same request, to be balanced by an equal
    number of request completions (while there will be one completion for
    that request). In this state, BFQ may refuse to serve I/O requests
    from other bfq_queues. The hang reported in [1] then follows.
    
    However, the above re-prepared requests undergo a requeue, thus the
    requeue_request hook of the active elevator is invoked for these
    requests, if set. This commit then addresses the above issue by
    properly implementing the hook requeue_request in BFQ.
    
    [1] https://marc.info/?l=linux-block&m=151211117608676Reported-by: default avatarIvan Kozik <ivan@ludios.org>
    Reported-by: default avatarAlban Browaeys <alban.browaeys@gmail.com>
    Tested-by: default avatarMike Galbraith <efault@gmx.de>
    Signed-off-by: default avatarPaolo Valente <paolo.valente@linaro.org>
    Signed-off-by: default avatarSerena Ziviani <ziviani.serena@gmail.com>
    Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
    a7877390
bfq-iosched.c 182 KB