Sophie

Sophie

distrib > Mageia > 8 > armv7hl > media > core-backports-src > by-pkgid > 86df85306f5432b2595a0b00aaebc12d > files > 42

kernel-5.16.18-1.mga8.src.rpm

From 872c1a638b9751061b11b64a240892c989d1c618 Mon Sep 17 00:00:00 2001
From: Song Liu <song@kernel.org>
Date: Tue, 8 Mar 2022 18:22:33 -0800
Subject: block: check morerequests for multiple_queues in
 blk_attempt_plug_merge

RAID arrays check/repair operations benefit a lot from merging requests.
If we only check the previous entry for merge attempt, many merge will be
missed. As a result, significant regression is observed for RAID check
and repair.

Fix this by checking more than just the previous entry when
plug->multiple_queues == true.

Fixes: d38a9c04c0d5 ("block: only check previous entry for plug merge attempt")
Cc: stable@vger.kernel.org # v5.16
Reported-by: Larkin Lowrey <llowrey@nuclearwinter.com>
Reported-by: Wilson Jonathan <i400sjon@gmail.com>
Reported-by: Roger Heflin <rogerheflin@gmail.com>
Signed-off-by: Song Liu <song@kernel.org>
---
 block/blk-merge.c | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/block/blk-merge.c b/block/blk-merge.c
index 893c1a60b701f..9bcae16a2bf45 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -1093,18 +1093,20 @@ bool blk_attempt_plug_merge(struct request_queue *q, struct bio *bio,
 	if (!plug || rq_list_empty(plug->mq_list))
 		return false;
 
-	/* check the previously added entry for a quick merge attempt */
-	rq = rq_list_peek(&plug->mq_list);
-	if (rq->q == q) {
-		/*
-		 * Only blk-mq multiple hardware queues case checks the rq in
-		 * the same queue, there should be only one such rq in a queue
-		 */
-		*same_queue_rq = true;
+	rq_list_for_each(&plug->mq_list, rq) {
+		if (rq->q == q) {
+			/*
+			 * Only blk-mq multiple hardware queues case checks the rq in
+			 * the same queue, there should be only one such rq in a queue
+			 */
+			*same_queue_rq = true;
 
-		if (blk_attempt_bio_merge(q, rq, bio, nr_segs, false) ==
-				BIO_MERGE_OK)
-			return true;
+			if (blk_attempt_bio_merge(q, rq, bio, nr_segs, false) ==
+			    BIO_MERGE_OK)
+				return true;
+		}
+		if (!plug->multiple_queues)
+			break;
 	}
 	return false;
 }
-- 
cgit