From: Daniel Wagner <dwagner@suse.de>
Date: Tue, 16 Feb 2021 18:02:22 +0100
Subject: [PATCH] nvme-loop: Introduce no merge flag for biovec
Patch-mainline: Never, fixed upstream but to invasive to backport
References: bsc#1174682
The biovec physical merging code is broken for the loop device.
blk-merge figures it possible to merge some segments but
blk_rq_map_sg() creates a mapping which using more segments.
This was fixed in a rework of the merging code. As this rework is too
big and invasive just disable the machinery for known broken
setups.
Signed-off-by: Daniel Wagner <dwagner@suse.de>
---
block/blk.h | 2 ++
drivers/nvme/target/loop.c | 1 +
include/linux/blkdev.h | 3 +++
3 files changed, 6 insertions(+)
diff --git a/block/blk.h b/block/blk.h
index 847eba8fd9c6..b47c8ae84116 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -162,6 +162,8 @@ static inline bool biovec_phys_mergeable(struct request_queue *q,
return false;
if ((addr1 | mask) != ((addr2 + vec2->bv_len - 1) | mask))
return false;
+ if (blk_queue_biovec_phys_nomerge(q))
+ return false;
return true;
}
diff --git a/drivers/nvme/target/loop.c b/drivers/nvme/target/loop.c
index 06827e534dec..2106412d5855 100644
--- a/drivers/nvme/target/loop.c
+++ b/drivers/nvme/target/loop.c
@@ -240,6 +240,7 @@ static int nvme_loop_init_hctx(struct blk_mq_hw_ctx *hctx, void *data,
BUG_ON(hctx_idx >= ctrl->ctrl.queue_count);
+ blk_queue_flag_set(QUEUE_FLAG_BIOVEC_PHYS_NOMERGE, hctx->queue);
hctx->driver_data = queue;
return 0;
}
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 17d9bdd825c4..b34f5541a2fe 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -709,6 +709,7 @@ struct request_queue {
#define QUEUE_FLAG_SCSI_PASSTHROUGH 27 /* queue supports SCSI commands */
#define QUEUE_FLAG_QUIESCED 28 /* queue has been quiesced */
#define QUEUE_FLAG_PREEMPT_ONLY 29 /* only process REQ_PREEMPT requests */
+#define QUEUE_FLAG_BIOVEC_PHYS_NOMERGE 30 /* disable phys biovec merge */
#define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \
(1 << QUEUE_FLAG_SAME_COMP) | \
@@ -741,6 +742,8 @@ bool blk_queue_flag_test_and_clear(unsigned int flag, struct request_queue *q);
#define blk_queue_dax(q) test_bit(QUEUE_FLAG_DAX, &(q)->queue_flags)
#define blk_queue_scsi_passthrough(q) \
test_bit(QUEUE_FLAG_SCSI_PASSTHROUGH, &(q)->queue_flags)
+#define blk_queue_biovec_phys_nomerge(q) \
+ test_bit(QUEUE_FLAG_BIOVEC_PHYS_NOMERGE, &(q)->queue_flags)
#define blk_noretry_request(rq) \
((rq)->cmd_flags & (REQ_FAILFAST_DEV|REQ_FAILFAST_TRANSPORT| \
--
2.29.2