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