Skip to content

Commit 34e0a27

Browse files
jankaraaxboe
authored andcommitted
block: do not reverse request order when flushing plug list
Commit 26fed4a ("block: flush plug based on hardware and software queue order") changed flushing of plug list to submit requests one device at a time. However while doing that it also started using list_add_tail() instead of list_add() used previously thus effectively submitting requests in reverse order. Also when forming a rq_list with remaining requests (in case two or more devices are used), we effectively reverse the ordering of the plug list for each device we process. Submitting requests in reverse order has negative impact on performance for rotational disks (when BFQ is not in use). We observe 10-25% regression in random 4k write throughput, as well as ~20% regression in MariaDB OLTP benchmark on rotational storage on btrfs filesystem. Fix the problem by preserving ordering of the plug list when inserting requests into the queuelist as well as by appending to requeue_list instead of prepending to it. Fixes: 26fed4a ("block: flush plug based on hardware and software queue order") Signed-off-by: Jan Kara <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent e2f2a39 commit 34e0a27

File tree

2 files changed

+9
-2
lines changed

2 files changed

+9
-2
lines changed

block/blk-mq.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2725,6 +2725,7 @@ static void blk_mq_dispatch_plug_list(struct blk_plug *plug, bool from_sched)
27252725
struct blk_mq_hw_ctx *this_hctx = NULL;
27262726
struct blk_mq_ctx *this_ctx = NULL;
27272727
struct request *requeue_list = NULL;
2728+
struct request **requeue_lastp = &requeue_list;
27282729
unsigned int depth = 0;
27292730
LIST_HEAD(list);
27302731

@@ -2735,10 +2736,10 @@ static void blk_mq_dispatch_plug_list(struct blk_plug *plug, bool from_sched)
27352736
this_hctx = rq->mq_hctx;
27362737
this_ctx = rq->mq_ctx;
27372738
} else if (this_hctx != rq->mq_hctx || this_ctx != rq->mq_ctx) {
2738-
rq_list_add(&requeue_list, rq);
2739+
rq_list_add_tail(&requeue_lastp, rq);
27392740
continue;
27402741
}
2741-
list_add_tail(&rq->queuelist, &list);
2742+
list_add(&rq->queuelist, &list);
27422743
depth++;
27432744
} while (!rq_list_empty(plug->mq_list));
27442745

include/linux/blk-mq.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,12 @@ static inline unsigned short req_get_ioprio(struct request *req)
228228
*(listptr) = rq; \
229229
} while (0)
230230

231+
#define rq_list_add_tail(lastpptr, rq) do { \
232+
(rq)->rq_next = NULL; \
233+
**(lastpptr) = rq; \
234+
*(lastpptr) = &rq->rq_next; \
235+
} while (0)
236+
231237
#define rq_list_pop(listptr) \
232238
({ \
233239
struct request *__req = NULL; \

0 commit comments

Comments
 (0)