|
Jan Kara |
13ff24 |
From: Jan Kara <jack@suse.cz>
|
|
Jan Kara |
13ff24 |
Date: Tue, 7 Mar 2023 13:42:09 +0100
|
|
Jan Kara |
13ff24 |
Subject: [PATCH] block: do not reverse request order when flushing plug list
|
|
Jan Kara |
13ff24 |
References: bsc#1208081 bsc#1208588 bsc#1208076
|
|
Jan Kara |
13ff24 |
Patch-mainline: v6.3-rc3
|
|
Jan Kara |
13ff24 |
Git-commit: 34e0a279a993debaff03158fc2fbf6a00c093643
|
|
Jan Kara |
13ff24 |
|
|
Jan Kara |
13ff24 |
Commit 26fed4ac4eab ("block: flush plug based on hardware and software
|
|
Jan Kara |
13ff24 |
queue order") changed flushing of plug list to submit requests one
|
|
Jan Kara |
13ff24 |
device at a time. However while doing that it also started using
|
|
Jan Kara |
13ff24 |
list_add_tail() instead of list_add() used previously thus effectively
|
|
Jan Kara |
13ff24 |
submitting requests in reverse order. Also when forming a rq_list with
|
|
Jan Kara |
13ff24 |
remaining requests (in case two or more devices are used), we
|
|
Jan Kara |
13ff24 |
effectively reverse the ordering of the plug list for each device we
|
|
Jan Kara |
13ff24 |
process. Submitting requests in reverse order has negative impact on
|
|
Jan Kara |
13ff24 |
performance for rotational disks (when BFQ is not in use). We observe
|
|
Jan Kara |
13ff24 |
10-25% regression in random 4k write throughput on rotational storage on
|
|
Jan Kara |
13ff24 |
btrfs filesystem.
|
|
Jan Kara |
13ff24 |
|
|
Jan Kara |
13ff24 |
Fix the problem by preserving ordering of the plug list when inserting
|
|
Jan Kara |
13ff24 |
requests into the queuelist as well as by appending to requeue_list
|
|
Jan Kara |
13ff24 |
instead of prepending to it.
|
|
Jan Kara |
13ff24 |
|
|
Jan Kara |
13ff24 |
Fixes: 26fed4ac4eab ("block: flush plug based on hardware and software queue order")
|
|
Jan Kara |
13ff24 |
Signed-off-by: Jan Kara <jack@suse.cz>
|
|
Jan Kara |
13ff24 |
Reviewed-by: Christoph Hellwig <hch@lst.de>
|
|
Jan Kara |
13ff24 |
Link: https://lore.kernel.org/r/20230313093002.11756-1-jack@suse.cz
|
|
Jan Kara |
13ff24 |
Signed-off-by: Jens Axboe <axboe@kernel.dk>
|
|
Jan Kara |
13ff24 |
---
|
|
Jan Kara |
13ff24 |
block/blk-mq.c | 5 +++--
|
|
Jan Kara |
13ff24 |
include/linux/blk-mq.h | 6 ++++++
|
|
Jan Kara |
13ff24 |
2 files changed, 9 insertions(+), 2 deletions(-)
|
|
Jan Kara |
13ff24 |
|
|
Jan Kara |
13ff24 |
diff --git a/block/blk-mq.c b/block/blk-mq.c
|
|
Jan Kara |
13ff24 |
index d0cb2ef18fe2..cf1a39adf9a5 100644
|
|
Jan Kara |
13ff24 |
--- a/block/blk-mq.c
|
|
Jan Kara |
13ff24 |
+++ b/block/blk-mq.c
|
|
Jan Kara |
13ff24 |
@@ -2725,6 +2725,7 @@ static void blk_mq_dispatch_plug_list(struct blk_plug *plug, bool from_sched)
|
|
Jan Kara |
13ff24 |
struct blk_mq_hw_ctx *this_hctx = NULL;
|
|
Jan Kara |
13ff24 |
struct blk_mq_ctx *this_ctx = NULL;
|
|
Jan Kara |
13ff24 |
struct request *requeue_list = NULL;
|
|
Jan Kara |
13ff24 |
+ struct request **requeue_lastp = &requeue_list;
|
|
Jan Kara |
13ff24 |
unsigned int depth = 0;
|
|
Jan Kara |
13ff24 |
LIST_HEAD(list);
|
|
Jan Kara |
13ff24 |
|
|
Jan Kara |
13ff24 |
@@ -2735,10 +2736,10 @@ static void blk_mq_dispatch_plug_list(struct blk_plug *plug, bool from_sched)
|
|
Jan Kara |
13ff24 |
this_hctx = rq->mq_hctx;
|
|
Jan Kara |
13ff24 |
this_ctx = rq->mq_ctx;
|
|
Jan Kara |
13ff24 |
} else if (this_hctx != rq->mq_hctx || this_ctx != rq->mq_ctx) {
|
|
Jan Kara |
13ff24 |
- rq_list_add(&requeue_list, rq);
|
|
Jan Kara |
13ff24 |
+ rq_list_add_tail(&requeue_lastp, rq);
|
|
Jan Kara |
13ff24 |
continue;
|
|
Jan Kara |
13ff24 |
}
|
|
Jan Kara |
13ff24 |
- list_add_tail(&rq->queuelist, &list);
|
|
Jan Kara |
13ff24 |
+ list_add(&rq->queuelist, &list);
|
|
Jan Kara |
13ff24 |
depth++;
|
|
Jan Kara |
13ff24 |
} while (!rq_list_empty(plug->mq_list));
|
|
Jan Kara |
13ff24 |
|
|
Jan Kara |
13ff24 |
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
|
|
Jan Kara |
13ff24 |
index dd5ce1137f04..de0b0c3e7395 100644
|
|
Jan Kara |
13ff24 |
--- a/include/linux/blk-mq.h
|
|
Jan Kara |
13ff24 |
+++ b/include/linux/blk-mq.h
|
|
Jan Kara |
13ff24 |
@@ -228,6 +228,12 @@ static inline unsigned short req_get_ioprio(struct request *req)
|
|
Jan Kara |
13ff24 |
*(listptr) = rq; \
|
|
Jan Kara |
13ff24 |
} while (0)
|
|
Jan Kara |
13ff24 |
|
|
Jan Kara |
13ff24 |
+#define rq_list_add_tail(lastpptr, rq) do { \
|
|
Jan Kara |
13ff24 |
+ (rq)->rq_next = NULL; \
|
|
Jan Kara |
13ff24 |
+ **(lastpptr) = rq; \
|
|
Jan Kara |
13ff24 |
+ *(lastpptr) = &rq->rq_next; \
|
|
Jan Kara |
13ff24 |
+} while (0)
|
|
Jan Kara |
13ff24 |
+
|
|
Jan Kara |
13ff24 |
#define rq_list_pop(listptr) \
|
|
Jan Kara |
13ff24 |
({ \
|
|
Jan Kara |
13ff24 |
struct request *__req = NULL; \
|
|
Jan Kara |
13ff24 |
--
|
|
Jan Kara |
13ff24 |
2.35.3
|
|
Jan Kara |
13ff24 |
|