lkml.org 
[lkml]   [2019]   [Mar]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 5.0 198/262] block, bfq: fix in-service-queue check for queue merging
    Date
    From: Paolo Valente <paolo.valente@linaro.org>

    [ Upstream commit 058fdecc6de7cdecbf4c59b851e80eb2d6c5295f ]

    When a new I/O request arrives for a bfq_queue, say Q, bfq checks
    whether that request is close to
    (a) the head request of some other queue waiting to be served, or
    (b) the last request dispatched for the in-service queue (in case Q
    itself is not the in-service queue)

    If a queue, say Q2, is found for which the above condition holds, then
    bfq merges Q and Q2, to hopefully get a more sequential I/O in the
    resulting merged queue, and thus a possibly higher throughput.

    Case (b) is checked by comparing the new request for Q with the last
    request dispatched, assuming that the latter necessarily belonged to the
    in-service queue. Unfortunately, this assumption is no longer always
    correct, since commit d0edc2473be9 ("block, bfq: inject other-queue I/O
    into seeky idle queues on NCQ flash").

    When the assumption does not hold, queues that must not be merged may be
    merged, causing unexpected loss of control on per-queue service
    guarantees.

    This commit solves this problem by adding an extra field, which stores
    the actual last request dispatched for the in-service queue, and by
    using this new field to correctly check case (b).

    Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
    Signed-off-by: Jens Axboe <axboe@kernel.dk>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    block/bfq-iosched.c | 5 ++++-
    block/bfq-iosched.h | 3 +++
    2 files changed, 7 insertions(+), 1 deletion(-)

    diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
    index cd307767a134..f010810c095f 100644
    --- a/block/bfq-iosched.c
    +++ b/block/bfq-iosched.c
    @@ -2224,7 +2224,8 @@ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq,

    if (in_service_bfqq && in_service_bfqq != bfqq &&
    likely(in_service_bfqq != &bfqd->oom_bfqq) &&
    - bfq_rq_close_to_sector(io_struct, request, bfqd->last_position) &&
    + bfq_rq_close_to_sector(io_struct, request,
    + bfqd->in_serv_last_pos) &&
    bfqq->entity.parent == in_service_bfqq->entity.parent &&
    bfq_may_be_close_cooperator(bfqq, in_service_bfqq)) {
    new_bfqq = bfq_setup_merge(bfqq, in_service_bfqq);
    @@ -2764,6 +2765,8 @@ static void bfq_update_peak_rate(struct bfq_data *bfqd, struct request *rq)
    bfq_update_rate_reset(bfqd, rq);
    update_last_values:
    bfqd->last_position = blk_rq_pos(rq) + blk_rq_sectors(rq);
    + if (RQ_BFQQ(rq) == bfqd->in_service_queue)
    + bfqd->in_serv_last_pos = bfqd->last_position;
    bfqd->last_dispatch = now_ns;
    }

    diff --git a/block/bfq-iosched.h b/block/bfq-iosched.h
    index 0b02bf302de0..746bd570b85a 100644
    --- a/block/bfq-iosched.h
    +++ b/block/bfq-iosched.h
    @@ -537,6 +537,9 @@ struct bfq_data {
    /* on-disk position of the last served request */
    sector_t last_position;

    + /* position of the last served request for the in-service queue */
    + sector_t in_serv_last_pos;
    +
    /* time of last request completion (ns) */
    u64 last_completion;

    --
    2.19.1
    \
     
     \ /
      Last update: 2019-03-27 20:18    [W:4.144 / U:0.016 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site