Skip to content

Commit b6d2b05

Browse files
bvanasscheaxboe
authored andcommitted
mq-deadline: Fix request accounting
The block layer may call the I/O scheduler .finish_request() callback without having called the .insert_requests() callback. Make sure that the mq-deadline I/O statistics are correct if the block layer inserts an I/O request that bypasses the I/O scheduler. This patch prevents that lower priority I/O is delayed longer than necessary for mixed I/O priority workloads. Cc: Niklas Cassel <[email protected]> Cc: Damien Le Moal <[email protected]> Cc: Hannes Reinecke <[email protected]> Reported-by: Niklas Cassel <[email protected]> Fixes: 08a9ad8 ("block/mq-deadline: Add cgroup support") Signed-off-by: Bart Van Assche <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Niklas Cassel <[email protected]> Tested-by: Niklas Cassel <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent a9ed27a commit b6d2b05

File tree

1 file changed

+11
-5
lines changed

1 file changed

+11
-5
lines changed

block/mq-deadline.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,7 @@ static void dd_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq,
711711

712712
prio = ioprio_class_to_prio[ioprio_class];
713713
dd_count(dd, inserted, prio);
714+
rq->elv.priv[0] = (void *)(uintptr_t)1;
714715

715716
if (blk_mq_sched_try_insert_merge(q, rq, &free)) {
716717
blk_mq_free_requests(&free);
@@ -759,12 +760,10 @@ static void dd_insert_requests(struct blk_mq_hw_ctx *hctx,
759760
spin_unlock(&dd->lock);
760761
}
761762

762-
/*
763-
* Nothing to do here. This is defined only to ensure that .finish_request
764-
* method is called upon request completion.
765-
*/
763+
/* Callback from inside blk_mq_rq_ctx_init(). */
766764
static void dd_prepare_request(struct request *rq)
767765
{
766+
rq->elv.priv[0] = NULL;
768767
}
769768

770769
/*
@@ -791,7 +790,14 @@ static void dd_finish_request(struct request *rq)
791790
const enum dd_prio prio = ioprio_class_to_prio[ioprio_class];
792791
struct dd_per_prio *per_prio = &dd->per_prio[prio];
793792

794-
dd_count(dd, completed, prio);
793+
/*
794+
* The block layer core may call dd_finish_request() without having
795+
* called dd_insert_requests(). Hence only update statistics for
796+
* requests for which dd_insert_requests() has been called. See also
797+
* blk_mq_request_bypass_insert().
798+
*/
799+
if (rq->elv.priv[0])
800+
dd_count(dd, completed, prio);
795801

796802
if (blk_queue_is_zoned(q)) {
797803
unsigned long flags;

0 commit comments

Comments
 (0)