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