From: Jens Axboe Date: Fri, 11 Mar 2022 17:21:43 +0000 (-0700) Subject: block: ensure plug merging checks the correct queue at least once X-Git-Tag: v5.17.2~1112 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=e8969bc51294af850b2b4e8c7efe81f25cd3676b;p=users%2Fdwmw2%2Flinux.git block: ensure plug merging checks the correct queue at least once commit 5b2050718d095cd3242d1f42aaaea3a2fec8e6f0 upstream. Song reports that a RAID rebuild workload runs much slower recently, and it is seeing a lot less merging than it did previously. The reason is that a previous commit reduced the amount of work we do for plug merging. RAID rebuild interleaves requests between disks, so a last-entry check in plug merging always misses a merge opportunity since we always find a different disk than what we are looking for. Modify the logic such that it's still a one-hit cache, but ensure that we check enough to find the right target before giving up. Fixes: d38a9c04c0d5 ("block: only check previous entry for plug merge attempt") Reported-and-tested-by: Song Liu Reviewed-by: Song Liu Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- diff --git a/block/blk-merge.c b/block/blk-merge.c index 4de34a332c9fd..d0addb4f5feb5 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -1089,12 +1089,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) { - if (blk_attempt_bio_merge(q, rq, bio, nr_segs, false) == - BIO_MERGE_OK) - return true; + rq_list_for_each(&plug->mq_list, rq) { + if (rq->q == q) { + if (blk_attempt_bio_merge(q, rq, bio, nr_segs, false) == + BIO_MERGE_OK) + return true; + break; + } + + /* + * Only keep iterating plug list for merges if we have multiple + * queues + */ + if (!plug->multiple_queues) + break; } return false; }