From e6e31258c75fab182501d58fca427529c2019e75 Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Tue, 21 May 2019 09:01:40 +0200 Subject: [PATCH 1972/2944] alinux: block: don't decrement nr_phys_segments for physically contigous segments fix #29327388 This patch is inspired by commit eded341c085b ("don't decrement nr_phys_segments for physically contigous segments"). Now the ll_merge_requests_fn() will reduces nr_phys_segments by one if the last segment of the previous, and the first segment of the next segment are contigous. But that will mismatch the segment numbers when handling discard request for virtio_block and nvme, moreover if nvme queue selects IO scheduler, that also will mistrigger the single segment optimization in the nvme-pci driver. Thus we should not decrement nr_phys_segments in ll_merge_requests_fn(). But in __blk_recalc_rq_segments(), if we re-calculate the segments of one request, we may get a different segment number, due to it will merge physically contigous segments here. Originally we should simply remove the bvec merging optimization under the assumption that most users already build good enough bvecs, but we do not want to touch so many core logics here, which may introduce more issues. So we can simply not allow to merge contigous segments between 2 bios to fix this issue, and this is not in the fast path, which will not affect the performance. Fixes: dff824b2aadb ("nvme-pci: optimize mapping of small single segment requests"). Signed-off-by: Baolin Wang Acked-by: Joseph Qi --- block/blk-merge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/blk-merge.c b/block/blk-merge.c index 7efa8c3..1cd480e 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -288,6 +288,7 @@ static unsigned int __blk_recalc_rq_segments(struct request_queue *q, seg_size = bv.bv_len; } bbio = bio; + prev = 0; } if (nr_phys_segs == 1 && seg_size > fbio->bi_seg_front_size) @@ -603,7 +604,6 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req, req->bio->bi_seg_front_size = seg_size; if (next->nr_phys_segments == 1) next->biotail->bi_seg_back_size = seg_size; - total_phys_segments--; } if (total_phys_segments > queue_max_segments(q)) -- 1.8.3.1