public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCHv5 0/9] block integrity merging and counting
@ 2024-09-13 18:28 Keith Busch
  2024-09-13 18:28 ` [PATCHv5 1/9] blk-mq: unconditional nr_integrity_segments Keith Busch
                   ` (9 more replies)
  0 siblings, 10 replies; 15+ messages in thread
From: Keith Busch @ 2024-09-13 18:28 UTC (permalink / raw)
  To: axboe, hch, martin.petersen, linux-block, linux-nvme, linux-scsi
  Cc: sagi, Keith Busch

From: Keith Busch <kbusch@kernel.org>

Some fixes and cleanups to counting integrity segments when metadata is
used. This addresses merging issues when integrity data is present.

Changes from v3:

  Dropped the trivial nr_integerity_segments helper

  Fixed sg mapping sanity check

  Added reviews

  Fixed commit log typos

Keith Busch (9):
  blk-mq: unconditional nr_integrity_segments
  blk-mq: set the nr_integrity_segments from bio
  blk-integrity: properly account for segments
  blk-integrity: consider entire bio list for merging
  block: provide a request helper for user integrity segments
  scsi: use request to get integrity segments
  nvme-rdma: use request to get integrity segments
  block: unexport blk_rq_count_integrity_sg
  blk-integrity: improved sg segment mapping

 block/bio-integrity.c         |  1 -
 block/blk-integrity.c         | 36 ++++++++++++++++++++++++-----------
 block/blk-merge.c             |  4 ++++
 block/blk-mq.c                |  5 +++--
 drivers/nvme/host/ioctl.c     |  6 ++----
 drivers/nvme/host/rdma.c      |  6 +++---
 drivers/scsi/scsi_lib.c       | 12 +++---------
 include/linux/blk-integrity.h | 15 +++++++++++----
 include/linux/blk-mq.h        |  3 ---
 9 files changed, 51 insertions(+), 37 deletions(-)

-- 
2.43.5


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCHv5 1/9] blk-mq: unconditional nr_integrity_segments
  2024-09-13 18:28 [PATCHv5 0/9] block integrity merging and counting Keith Busch
@ 2024-09-13 18:28 ` Keith Busch
  2024-09-13 18:28 ` [PATCHv5 2/9] blk-mq: set the nr_integrity_segments from bio Keith Busch
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Keith Busch @ 2024-09-13 18:28 UTC (permalink / raw)
  To: axboe, hch, martin.petersen, linux-block, linux-nvme, linux-scsi
  Cc: sagi, Keith Busch

From: Keith Busch <kbusch@kernel.org>

Always defining the field will make using it easier and less error prone
in future patches.

There shouldn't be any downside to this: the field fits in what would
otherwise be a 2-byte hole, so we're not saving space by conditionally
leaving it out.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
---
 block/blk-mq.c         | 2 --
 include/linux/blk-mq.h | 3 ---
 2 files changed, 5 deletions(-)

diff --git a/block/blk-mq.c b/block/blk-mq.c
index 3f1f7d0b3ff35..ef3a2ed499563 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -376,9 +376,7 @@ static struct request *blk_mq_rq_ctx_init(struct blk_mq_alloc_data *data,
 	rq->io_start_time_ns = 0;
 	rq->stats_sectors = 0;
 	rq->nr_phys_segments = 0;
-#if defined(CONFIG_BLK_DEV_INTEGRITY)
 	rq->nr_integrity_segments = 0;
-#endif
 	rq->end_io = NULL;
 	rq->end_io_data = NULL;
 
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
index 8d304b1d16b15..4fecf46ef681b 100644
--- a/include/linux/blk-mq.h
+++ b/include/linux/blk-mq.h
@@ -149,10 +149,7 @@ struct request {
 	 * physical address coalescing is performed.
 	 */
 	unsigned short nr_phys_segments;
-
-#ifdef CONFIG_BLK_DEV_INTEGRITY
 	unsigned short nr_integrity_segments;
-#endif
 
 #ifdef CONFIG_BLK_INLINE_ENCRYPTION
 	struct bio_crypt_ctx *crypt_ctx;
-- 
2.43.5


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCHv5 2/9] blk-mq: set the nr_integrity_segments from bio
  2024-09-13 18:28 [PATCHv5 0/9] block integrity merging and counting Keith Busch
  2024-09-13 18:28 ` [PATCHv5 1/9] blk-mq: unconditional nr_integrity_segments Keith Busch
@ 2024-09-13 18:28 ` Keith Busch
  2024-09-13 18:28 ` [PATCHv5 3/9] blk-integrity: properly account for segments Keith Busch
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Keith Busch @ 2024-09-13 18:28 UTC (permalink / raw)
  To: axboe, hch, martin.petersen, linux-block, linux-nvme, linux-scsi
  Cc: sagi, Keith Busch

From: Keith Busch <kbusch@kernel.org>

This value is used for merging considerations, so it needs to be
accurate.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
---
 block/blk-mq.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/block/blk-mq.c b/block/blk-mq.c
index ef3a2ed499563..82219f0e9a256 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -2544,6 +2544,9 @@ static void blk_mq_bio_to_request(struct request *rq, struct bio *bio,
 	rq->__sector = bio->bi_iter.bi_sector;
 	rq->write_hint = bio->bi_write_hint;
 	blk_rq_bio_prep(rq, bio, nr_segs);
+	if (bio_integrity(bio))
+		rq->nr_integrity_segments = blk_rq_count_integrity_sg(rq->q,
+								      bio);
 
 	/* This can't fail, since GFP_NOIO includes __GFP_DIRECT_RECLAIM. */
 	err = blk_crypto_rq_bio_prep(rq, bio, GFP_NOIO);
-- 
2.43.5


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCHv5 3/9] blk-integrity: properly account for segments
  2024-09-13 18:28 [PATCHv5 0/9] block integrity merging and counting Keith Busch
  2024-09-13 18:28 ` [PATCHv5 1/9] blk-mq: unconditional nr_integrity_segments Keith Busch
  2024-09-13 18:28 ` [PATCHv5 2/9] blk-mq: set the nr_integrity_segments from bio Keith Busch
@ 2024-09-13 18:28 ` Keith Busch
  2024-09-13 18:28 ` [PATCHv5 4/9] blk-integrity: consider entire bio list for merging Keith Busch
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Keith Busch @ 2024-09-13 18:28 UTC (permalink / raw)
  To: axboe, hch, martin.petersen, linux-block, linux-nvme, linux-scsi
  Cc: sagi, Keith Busch

From: Keith Busch <kbusch@kernel.org>

Both types of merging when integrity data is used are miscounting the
segments:

Merging two requests wasn't accounting for the new segment count, so add
the "next" segment count to the first on a successful merge to ensure
this value is accurate.

Merging a bio into an existing request was double counting the bio's
segments, even if the merge failed later on. Move the segment accounting
to the end when the merge is successful.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
---
 block/blk-integrity.c | 2 --
 block/blk-merge.c     | 4 ++++
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/block/blk-integrity.c b/block/blk-integrity.c
index 010decc892eaa..afd101555d3cb 100644
--- a/block/blk-integrity.c
+++ b/block/blk-integrity.c
@@ -153,8 +153,6 @@ bool blk_integrity_merge_bio(struct request_queue *q, struct request *req,
 	    q->limits.max_integrity_segments)
 		return false;
 
-	req->nr_integrity_segments += nr_integrity_segs;
-
 	return true;
 }
 
diff --git a/block/blk-merge.c b/block/blk-merge.c
index 56769c4bcd799..ad763ec313b6a 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -639,6 +639,9 @@ static inline int ll_new_hw_segment(struct request *req, struct bio *bio,
 	 * counters.
 	 */
 	req->nr_phys_segments += nr_phys_segs;
+	if (bio_integrity(bio))
+		req->nr_integrity_segments += blk_rq_count_integrity_sg(req->q,
+									bio);
 	return 1;
 
 no_merge:
@@ -731,6 +734,7 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req,
 
 	/* Merge is OK... */
 	req->nr_phys_segments = total_phys_segments;
+	req->nr_integrity_segments += next->nr_integrity_segments;
 	return 1;
 }
 
-- 
2.43.5


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCHv5 4/9] blk-integrity: consider entire bio list for merging
  2024-09-13 18:28 [PATCHv5 0/9] block integrity merging and counting Keith Busch
                   ` (2 preceding siblings ...)
  2024-09-13 18:28 ` [PATCHv5 3/9] blk-integrity: properly account for segments Keith Busch
@ 2024-09-13 18:28 ` Keith Busch
  2024-09-14  7:30   ` Christoph Hellwig
  2024-09-13 18:28 ` [PATCHv5 5/9] block: provide a request helper for user integrity segments Keith Busch
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 15+ messages in thread
From: Keith Busch @ 2024-09-13 18:28 UTC (permalink / raw)
  To: axboe, hch, martin.petersen, linux-block, linux-nvme, linux-scsi
  Cc: sagi, Keith Busch

From: Keith Busch <kbusch@kernel.org>

If a bio is merged to a request, the entire bio list is merged, so don't
temporarily detach it from its list when counting segments. In most
cases, bi_next will already be NULL, so detaching is usually a no-op.
But if the bio does have a list, the current code is miscounting the
segments for the resulting merge.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
---
 block/blk-integrity.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/block/blk-integrity.c b/block/blk-integrity.c
index afd101555d3cb..84065691aaed0 100644
--- a/block/blk-integrity.c
+++ b/block/blk-integrity.c
@@ -134,7 +134,6 @@ bool blk_integrity_merge_bio(struct request_queue *q, struct request *req,
 			     struct bio *bio)
 {
 	int nr_integrity_segs;
-	struct bio *next = bio->bi_next;
 
 	if (blk_integrity_rq(req) == 0 && bio_integrity(bio) == NULL)
 		return true;
@@ -145,10 +144,7 @@ bool blk_integrity_merge_bio(struct request_queue *q, struct request *req,
 	if (bio_integrity(req->bio)->bip_flags != bio_integrity(bio)->bip_flags)
 		return false;
 
-	bio->bi_next = NULL;
 	nr_integrity_segs = blk_rq_count_integrity_sg(q, bio);
-	bio->bi_next = next;
-
 	if (req->nr_integrity_segments + nr_integrity_segs >
 	    q->limits.max_integrity_segments)
 		return false;
-- 
2.43.5


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCHv5 5/9] block: provide a request helper for user integrity segments
  2024-09-13 18:28 [PATCHv5 0/9] block integrity merging and counting Keith Busch
                   ` (3 preceding siblings ...)
  2024-09-13 18:28 ` [PATCHv5 4/9] blk-integrity: consider entire bio list for merging Keith Busch
@ 2024-09-13 18:28 ` Keith Busch
  2024-09-13 18:28 ` [PATCHv5 6/9] scsi: use request to get " Keith Busch
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Keith Busch @ 2024-09-13 18:28 UTC (permalink / raw)
  To: axboe, hch, martin.petersen, linux-block, linux-nvme, linux-scsi
  Cc: sagi, Keith Busch, Kanchan Joshi

From: Keith Busch <kbusch@kernel.org>

Provide a helper to keep the request flags and nr_integrity_segments in
sync with the bio's integrity payload. This is an integrity equivalent
to the normal data helper function, 'blk_rq_map_user()'.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: Kanchan Joshi <joshi.k@samsung.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
---
 block/bio-integrity.c         |  1 -
 block/blk-integrity.c         | 14 ++++++++++++++
 drivers/nvme/host/ioctl.c     |  6 ++----
 include/linux/blk-integrity.h |  9 +++++++++
 4 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/block/bio-integrity.c b/block/bio-integrity.c
index 8d1fb38f745f9..357a022eed411 100644
--- a/block/bio-integrity.c
+++ b/block/bio-integrity.c
@@ -371,7 +371,6 @@ int bio_integrity_map_user(struct bio *bio, void __user *ubuf, ssize_t bytes,
 		kfree(bvec);
 	return ret;
 }
-EXPORT_SYMBOL_GPL(bio_integrity_map_user);
 
 /**
  * bio_integrity_prep - Prepare bio for integrity I/O
diff --git a/block/blk-integrity.c b/block/blk-integrity.c
index 84065691aaed0..ddc742d58330b 100644
--- a/block/blk-integrity.c
+++ b/block/blk-integrity.c
@@ -107,6 +107,20 @@ int blk_rq_map_integrity_sg(struct request_queue *q, struct bio *bio,
 }
 EXPORT_SYMBOL(blk_rq_map_integrity_sg);
 
+int blk_rq_integrity_map_user(struct request *rq, void __user *ubuf,
+			      ssize_t bytes, u32 seed)
+{
+	int ret = bio_integrity_map_user(rq->bio, ubuf, bytes, seed);
+
+	if (ret)
+		return ret;
+
+	rq->nr_integrity_segments = blk_rq_count_integrity_sg(rq->q, rq->bio);
+	rq->cmd_flags |= REQ_INTEGRITY;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(blk_rq_integrity_map_user);
+
 bool blk_integrity_merge_rq(struct request_queue *q, struct request *req,
 			    struct request *next)
 {
diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c
index 1d769c842fbf5..b9b79ccfabf8a 100644
--- a/drivers/nvme/host/ioctl.c
+++ b/drivers/nvme/host/ioctl.c
@@ -3,7 +3,6 @@
  * Copyright (c) 2011-2014, Intel Corporation.
  * Copyright (c) 2017-2021 Christoph Hellwig.
  */
-#include <linux/bio-integrity.h>
 #include <linux/blk-integrity.h>
 #include <linux/ptrace.h>	/* for force_successful_syscall_return */
 #include <linux/nvme_ioctl.h>
@@ -153,11 +152,10 @@ static int nvme_map_user_request(struct request *req, u64 ubuffer,
 		bio_set_dev(bio, bdev);
 
 	if (has_metadata) {
-		ret = bio_integrity_map_user(bio, meta_buffer, meta_len,
-					     meta_seed);
+		ret = blk_rq_integrity_map_user(req, meta_buffer, meta_len,
+						meta_seed);
 		if (ret)
 			goto out_unmap;
-		req->cmd_flags |= REQ_INTEGRITY;
 	}
 
 	return ret;
diff --git a/include/linux/blk-integrity.h b/include/linux/blk-integrity.h
index de98049b7ded9..793dbb1e0672d 100644
--- a/include/linux/blk-integrity.h
+++ b/include/linux/blk-integrity.h
@@ -28,6 +28,8 @@ static inline bool queue_limits_stack_integrity_bdev(struct queue_limits *t,
 int blk_rq_map_integrity_sg(struct request_queue *, struct bio *,
 				   struct scatterlist *);
 int blk_rq_count_integrity_sg(struct request_queue *, struct bio *);
+int blk_rq_integrity_map_user(struct request *rq, void __user *ubuf,
+			      ssize_t bytes, u32 seed);
 
 static inline bool
 blk_integrity_queue_supports_integrity(struct request_queue *q)
@@ -102,6 +104,13 @@ static inline int blk_rq_map_integrity_sg(struct request_queue *q,
 {
 	return 0;
 }
+static inline int blk_rq_integrity_map_user(struct request *rq,
+					    void __user *ubuf,
+					    ssize_t bytes,
+					    u32 seed)
+{
+	return -EINVAL;
+}
 static inline struct blk_integrity *bdev_get_integrity(struct block_device *b)
 {
 	return NULL;
-- 
2.43.5


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCHv5 6/9] scsi: use request to get integrity segments
  2024-09-13 18:28 [PATCHv5 0/9] block integrity merging and counting Keith Busch
                   ` (4 preceding siblings ...)
  2024-09-13 18:28 ` [PATCHv5 5/9] block: provide a request helper for user integrity segments Keith Busch
@ 2024-09-13 18:28 ` Keith Busch
  2024-09-13 18:28 ` [PATCHv5 7/9] nvme-rdma: " Keith Busch
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Keith Busch @ 2024-09-13 18:28 UTC (permalink / raw)
  To: axboe, hch, martin.petersen, linux-block, linux-nvme, linux-scsi
  Cc: sagi, Keith Busch, Kanchan Joshi

From: Keith Busch <kbusch@kernel.org>

The request tracks the integrity segments already, so no need to recount
the segments again.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: Kanchan Joshi <joshi.k@samsung.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
---
 drivers/scsi/scsi_lib.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 3958a6d14bf45..c602b0af745ca 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1175,8 +1175,7 @@ blk_status_t scsi_alloc_sgtables(struct scsi_cmnd *cmd)
 			goto out_free_sgtables;
 		}
 
-		ivecs = blk_rq_count_integrity_sg(rq->q, rq->bio);
-
+		ivecs = rq->nr_integrity_segments;
 		if (sg_alloc_table_chained(&prot_sdb->table, ivecs,
 				prot_sdb->table.sgl,
 				SCSI_INLINE_PROT_SG_CNT)) {
-- 
2.43.5


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCHv5 7/9] nvme-rdma: use request to get integrity segments
  2024-09-13 18:28 [PATCHv5 0/9] block integrity merging and counting Keith Busch
                   ` (5 preceding siblings ...)
  2024-09-13 18:28 ` [PATCHv5 6/9] scsi: use request to get " Keith Busch
@ 2024-09-13 18:28 ` Keith Busch
  2024-09-13 18:28 ` [PATCHv5 8/9] block: unexport blk_rq_count_integrity_sg Keith Busch
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Keith Busch @ 2024-09-13 18:28 UTC (permalink / raw)
  To: axboe, hch, martin.petersen, linux-block, linux-nvme, linux-scsi
  Cc: sagi, Keith Busch, Kanchan Joshi

From: Keith Busch <kbusch@kernel.org>

The request tracks the integrity segments already, so no need to recount
the segments again.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: Kanchan Joshi <joshi.k@samsung.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
---
 drivers/nvme/host/rdma.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c
index 15b5e06039a5f..256466bdaee7c 100644
--- a/drivers/nvme/host/rdma.c
+++ b/drivers/nvme/host/rdma.c
@@ -1496,7 +1496,7 @@ static int nvme_rdma_dma_map_req(struct ib_device *ibdev, struct request *rq,
 		req->metadata_sgl->sg_table.sgl =
 			(struct scatterlist *)(req->metadata_sgl + 1);
 		ret = sg_alloc_table_chained(&req->metadata_sgl->sg_table,
-				blk_rq_count_integrity_sg(rq->q, rq->bio),
+				rq->nr_integrity_segments,
 				req->metadata_sgl->sg_table.sgl,
 				NVME_INLINE_METADATA_SG_CNT);
 		if (unlikely(ret)) {
-- 
2.43.5


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCHv5 8/9] block: unexport blk_rq_count_integrity_sg
  2024-09-13 18:28 [PATCHv5 0/9] block integrity merging and counting Keith Busch
                   ` (6 preceding siblings ...)
  2024-09-13 18:28 ` [PATCHv5 7/9] nvme-rdma: " Keith Busch
@ 2024-09-13 18:28 ` Keith Busch
  2024-09-13 18:28 ` [PATCHv5 9/9] blk-integrity: improved sg segment mapping Keith Busch
  2024-09-13 18:37 ` [PATCHv5 0/9] block integrity merging and counting Jens Axboe
  9 siblings, 0 replies; 15+ messages in thread
From: Keith Busch @ 2024-09-13 18:28 UTC (permalink / raw)
  To: axboe, hch, martin.petersen, linux-block, linux-nvme, linux-scsi
  Cc: sagi, Keith Busch

From: Keith Busch <kbusch@kernel.org>

There are no external users of this.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
---
 block/blk-integrity.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/block/blk-integrity.c b/block/blk-integrity.c
index ddc742d58330b..1d82b18e06f8e 100644
--- a/block/blk-integrity.c
+++ b/block/blk-integrity.c
@@ -53,7 +53,6 @@ int blk_rq_count_integrity_sg(struct request_queue *q, struct bio *bio)
 
 	return segments;
 }
-EXPORT_SYMBOL(blk_rq_count_integrity_sg);
 
 /**
  * blk_rq_map_integrity_sg - Map integrity metadata into a scatterlist
-- 
2.43.5


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCHv5 9/9] blk-integrity: improved sg segment mapping
  2024-09-13 18:28 [PATCHv5 0/9] block integrity merging and counting Keith Busch
                   ` (7 preceding siblings ...)
  2024-09-13 18:28 ` [PATCHv5 8/9] block: unexport blk_rq_count_integrity_sg Keith Busch
@ 2024-09-13 18:28 ` Keith Busch
  2024-09-13 18:37 ` [PATCHv5 0/9] block integrity merging and counting Jens Axboe
  9 siblings, 0 replies; 15+ messages in thread
From: Keith Busch @ 2024-09-13 18:28 UTC (permalink / raw)
  To: axboe, hch, martin.petersen, linux-block, linux-nvme, linux-scsi
  Cc: sagi, Keith Busch

From: Keith Busch <kbusch@kernel.org>

Make the integrity mapping more like data mapping, blk_rq_map_sg. Use
the request to validate the segment count, and update the callers so
they don't have to.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
---
 block/blk-integrity.c         | 15 +++++++++++----
 drivers/nvme/host/rdma.c      |  4 ++--
 drivers/scsi/scsi_lib.c       | 11 +++--------
 include/linux/blk-integrity.h |  6 ++----
 4 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/block/blk-integrity.c b/block/blk-integrity.c
index 1d82b18e06f8e..549480aa2a069 100644
--- a/block/blk-integrity.c
+++ b/block/blk-integrity.c
@@ -62,19 +62,20 @@ int blk_rq_count_integrity_sg(struct request_queue *q, struct bio *bio)
  *
  * Description: Map the integrity vectors in request into a
  * scatterlist.  The scatterlist must be big enough to hold all
- * elements.  I.e. sized using blk_rq_count_integrity_sg().
+ * elements.  I.e. sized using blk_rq_count_integrity_sg() or
+ * rq->nr_integrity_segments.
  */
-int blk_rq_map_integrity_sg(struct request_queue *q, struct bio *bio,
-			    struct scatterlist *sglist)
+int blk_rq_map_integrity_sg(struct request *rq, struct scatterlist *sglist)
 {
 	struct bio_vec iv, ivprv = { NULL };
+	struct request_queue *q = rq->q;
 	struct scatterlist *sg = NULL;
+	struct bio *bio = rq->bio;
 	unsigned int segments = 0;
 	struct bvec_iter iter;
 	int prev = 0;
 
 	bio_for_each_integrity_vec(iv, bio, iter) {
-
 		if (prev) {
 			if (!biovec_phys_mergeable(q, &ivprv, &iv))
 				goto new_segment;
@@ -102,6 +103,12 @@ int blk_rq_map_integrity_sg(struct request_queue *q, struct bio *bio,
 	if (sg)
 		sg_mark_end(sg);
 
+	/*
+	 * Something must have been wrong if the figured number of segment
+	 * is bigger than number of req's physical integrity segments
+	 */
+	BUG_ON(segments > blk_rq_nr_phys_segments(rq));
+	BUG_ON(segments > queue_max_integrity_segments(q));
 	return segments;
 }
 EXPORT_SYMBOL(blk_rq_map_integrity_sg);
diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c
index 256466bdaee7c..c8fd0e8f02375 100644
--- a/drivers/nvme/host/rdma.c
+++ b/drivers/nvme/host/rdma.c
@@ -1504,8 +1504,8 @@ static int nvme_rdma_dma_map_req(struct ib_device *ibdev, struct request *rq,
 			goto out_unmap_sg;
 		}
 
-		req->metadata_sgl->nents = blk_rq_map_integrity_sg(rq->q,
-				rq->bio, req->metadata_sgl->sg_table.sgl);
+		req->metadata_sgl->nents = blk_rq_map_integrity_sg(rq,
+				req->metadata_sgl->sg_table.sgl);
 		*pi_count = ib_dma_map_sg(ibdev,
 					  req->metadata_sgl->sg_table.sgl,
 					  req->metadata_sgl->nents,
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index c602b0af745ca..c2f6d0e1c03e7 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1163,7 +1163,6 @@ blk_status_t scsi_alloc_sgtables(struct scsi_cmnd *cmd)
 
 	if (blk_integrity_rq(rq)) {
 		struct scsi_data_buffer *prot_sdb = cmd->prot_sdb;
-		int ivecs;
 
 		if (WARN_ON_ONCE(!prot_sdb)) {
 			/*
@@ -1175,19 +1174,15 @@ blk_status_t scsi_alloc_sgtables(struct scsi_cmnd *cmd)
 			goto out_free_sgtables;
 		}
 
-		ivecs = rq->nr_integrity_segments;
-		if (sg_alloc_table_chained(&prot_sdb->table, ivecs,
+		if (sg_alloc_table_chained(&prot_sdb->table,
+				rq->nr_integrity_segments,
 				prot_sdb->table.sgl,
 				SCSI_INLINE_PROT_SG_CNT)) {
 			ret = BLK_STS_RESOURCE;
 			goto out_free_sgtables;
 		}
 
-		count = blk_rq_map_integrity_sg(rq->q, rq->bio,
-						prot_sdb->table.sgl);
-		BUG_ON(count > ivecs);
-		BUG_ON(count > queue_max_integrity_segments(rq->q));
-
+		count = blk_rq_map_integrity_sg(rq, prot_sdb->table.sgl);
 		cmd->prot_sdb = prot_sdb;
 		cmd->prot_sdb->table.nents = count;
 	}
diff --git a/include/linux/blk-integrity.h b/include/linux/blk-integrity.h
index 793dbb1e0672d..676f8f860c474 100644
--- a/include/linux/blk-integrity.h
+++ b/include/linux/blk-integrity.h
@@ -25,8 +25,7 @@ static inline bool queue_limits_stack_integrity_bdev(struct queue_limits *t,
 }
 
 #ifdef CONFIG_BLK_DEV_INTEGRITY
-int blk_rq_map_integrity_sg(struct request_queue *, struct bio *,
-				   struct scatterlist *);
+int blk_rq_map_integrity_sg(struct request *, struct scatterlist *);
 int blk_rq_count_integrity_sg(struct request_queue *, struct bio *);
 int blk_rq_integrity_map_user(struct request *rq, void __user *ubuf,
 			      ssize_t bytes, u32 seed);
@@ -98,8 +97,7 @@ static inline int blk_rq_count_integrity_sg(struct request_queue *q,
 {
 	return 0;
 }
-static inline int blk_rq_map_integrity_sg(struct request_queue *q,
-					  struct bio *b,
+static inline int blk_rq_map_integrity_sg(struct request *q,
 					  struct scatterlist *s)
 {
 	return 0;
-- 
2.43.5


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCHv5 0/9] block integrity merging and counting
  2024-09-13 18:28 [PATCHv5 0/9] block integrity merging and counting Keith Busch
                   ` (8 preceding siblings ...)
  2024-09-13 18:28 ` [PATCHv5 9/9] blk-integrity: improved sg segment mapping Keith Busch
@ 2024-09-13 18:37 ` Jens Axboe
  9 siblings, 0 replies; 15+ messages in thread
From: Jens Axboe @ 2024-09-13 18:37 UTC (permalink / raw)
  To: hch, martin.petersen, linux-block, linux-nvme, linux-scsi,
	Keith Busch
  Cc: sagi, Keith Busch


On Fri, 13 Sep 2024 11:28:45 -0700, Keith Busch wrote:
> Some fixes and cleanups to counting integrity segments when metadata is
> used. This addresses merging issues when integrity data is present.
> 
> Changes from v3:
> 
>   Dropped the trivial nr_integerity_segments helper
> 
> [...]

Applied, thanks!

[1/9] blk-mq: unconditional nr_integrity_segments
      commit: 2b018086143d638de8d67ae5be6e8c1afb413193
[2/9] blk-mq: set the nr_integrity_segments from bio
      commit: 9c297eced59817f461be33e4c241820c5be4bcc1
[3/9] blk-integrity: properly account for segments
      commit: d148d7503456556859c7e4d354115215d8fb5016
[4/9] blk-integrity: consider entire bio list for merging
      commit: 0d7cb52fe417dde4bc9e8d01fadd8c0ec69612cd
[5/9] block: provide a request helper for user integrity segments
      commit: d2c5b1faccd5ef6352456f817e941945d3b3fe62
[6/9] scsi: use request to get integrity segments
      commit: 27c3785e94f003c664d9d867fbd62d1494546876
[7/9] nvme-rdma: use request to get integrity segments
      commit: f4330766bc0d14b5eb9459e616060d697e7b128e
[8/9] block: unexport blk_rq_count_integrity_sg
      commit: db5197b554fcb8fde0182af65e8e94bec414e342
[9/9] blk-integrity: improved sg segment mapping
      commit: b712a8c0be4d50cbeffe24b9af96921f28b6f939

Best regards,
-- 
Jens Axboe




^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCHv5 4/9] blk-integrity: consider entire bio list for merging
  2024-09-13 18:28 ` [PATCHv5 4/9] blk-integrity: consider entire bio list for merging Keith Busch
@ 2024-09-14  7:30   ` Christoph Hellwig
  2024-09-14 16:51     ` Keith Busch
  0 siblings, 1 reply; 15+ messages in thread
From: Christoph Hellwig @ 2024-09-14  7:30 UTC (permalink / raw)
  To: Keith Busch
  Cc: axboe, hch, martin.petersen, linux-block, linux-nvme, linux-scsi,
	sagi, Keith Busch

On Fri, Sep 13, 2024 at 11:28:49AM -0700, Keith Busch wrote:
> From: Keith Busch <kbusch@kernel.org>
> 
> If a bio is merged to a request, the entire bio list is merged, so don't
> temporarily detach it from its list when counting segments. In most
> cases, bi_next will already be NULL, so detaching is usually a no-op.
> But if the bio does have a list, the current code is miscounting the
> segments for the resulting merge.

As I explained in detail last round this is still wrong.  There is
no bio list here ever.


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCHv5 4/9] blk-integrity: consider entire bio list for merging
  2024-09-14  7:30   ` Christoph Hellwig
@ 2024-09-14 16:51     ` Keith Busch
  2024-09-16  6:44       ` Christoph Hellwig
  0 siblings, 1 reply; 15+ messages in thread
From: Keith Busch @ 2024-09-14 16:51 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Keith Busch, axboe, martin.petersen, linux-block, linux-nvme,
	linux-scsi, sagi

On Sat, Sep 14, 2024 at 09:30:12AM +0200, Christoph Hellwig wrote:
> On Fri, Sep 13, 2024 at 11:28:49AM -0700, Keith Busch wrote:
> > From: Keith Busch <kbusch@kernel.org>
> > 
> > If a bio is merged to a request, the entire bio list is merged, so don't
> > temporarily detach it from its list when counting segments. In most
> > cases, bi_next will already be NULL, so detaching is usually a no-op.
> > But if the bio does have a list, the current code is miscounting the
> > segments for the resulting merge.
> 
> As I explained in detail last round this is still wrong.  There is
> no bio list here ever.

Could you explain "wrong"? If we assume there is never bio list here,
then the current code is performing a useless no-op, and this patch
removes it. That's a good thing, no?

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCHv5 4/9] blk-integrity: consider entire bio list for merging
  2024-09-14 16:51     ` Keith Busch
@ 2024-09-16  6:44       ` Christoph Hellwig
  2024-09-16  8:40         ` Keith Busch
  0 siblings, 1 reply; 15+ messages in thread
From: Christoph Hellwig @ 2024-09-16  6:44 UTC (permalink / raw)
  To: Keith Busch
  Cc: Christoph Hellwig, Keith Busch, axboe, martin.petersen,
	linux-block, linux-nvme, linux-scsi, sagi

On Sat, Sep 14, 2024 at 10:51:10AM -0600, Keith Busch wrote:
> On Sat, Sep 14, 2024 at 09:30:12AM +0200, Christoph Hellwig wrote:
> > On Fri, Sep 13, 2024 at 11:28:49AM -0700, Keith Busch wrote:
> > > From: Keith Busch <kbusch@kernel.org>
> > > 
> > > If a bio is merged to a request, the entire bio list is merged, so don't
> > > temporarily detach it from its list when counting segments. In most
> > > cases, bi_next will already be NULL, so detaching is usually a no-op.
> > > But if the bio does have a list, the current code is miscounting the
> > > segments for the resulting merge.
> > 
> > As I explained in detail last round this is still wrong.  There is
> > no bio list here ever.
> 
> Could you explain "wrong"? If we assume there is never bio list here,
> then the current code is performing a useless no-op, and this patch
> removes it. That's a good thing, no?

The wrong thing primarily is the above commit log.  The code change
itself is correct, but we'd be better off killing the iteration over
the bio chain as well to make the code less confusing.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCHv5 4/9] blk-integrity: consider entire bio list for merging
  2024-09-16  6:44       ` Christoph Hellwig
@ 2024-09-16  8:40         ` Keith Busch
  0 siblings, 0 replies; 15+ messages in thread
From: Keith Busch @ 2024-09-16  8:40 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Keith Busch, axboe, martin.petersen, linux-block, linux-nvme,
	linux-scsi, sagi

On Mon, Sep 16, 2024 at 08:44:13AM +0200, Christoph Hellwig wrote:
> The wrong thing primarily is the above commit log.  The code change
> itself is correct, but we'd be better off killing the iteration over
> the bio chain as well to make the code less confusing.

Okay, gotcha. I mentioned the existing code is a no op in "most cases"
but it should just be "always". Maybe a sanity check with a WARN here is
appropriate too.

BTW, sorry for mislabeling the tags. The patch numbers changed a few
times in this series, and I pasted reviews from the a different message.

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2024-09-16  8:40 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-13 18:28 [PATCHv5 0/9] block integrity merging and counting Keith Busch
2024-09-13 18:28 ` [PATCHv5 1/9] blk-mq: unconditional nr_integrity_segments Keith Busch
2024-09-13 18:28 ` [PATCHv5 2/9] blk-mq: set the nr_integrity_segments from bio Keith Busch
2024-09-13 18:28 ` [PATCHv5 3/9] blk-integrity: properly account for segments Keith Busch
2024-09-13 18:28 ` [PATCHv5 4/9] blk-integrity: consider entire bio list for merging Keith Busch
2024-09-14  7:30   ` Christoph Hellwig
2024-09-14 16:51     ` Keith Busch
2024-09-16  6:44       ` Christoph Hellwig
2024-09-16  8:40         ` Keith Busch
2024-09-13 18:28 ` [PATCHv5 5/9] block: provide a request helper for user integrity segments Keith Busch
2024-09-13 18:28 ` [PATCHv5 6/9] scsi: use request to get " Keith Busch
2024-09-13 18:28 ` [PATCHv5 7/9] nvme-rdma: " Keith Busch
2024-09-13 18:28 ` [PATCHv5 8/9] block: unexport blk_rq_count_integrity_sg Keith Busch
2024-09-13 18:28 ` [PATCHv5 9/9] blk-integrity: improved sg segment mapping Keith Busch
2024-09-13 18:37 ` [PATCHv5 0/9] block integrity merging and counting Jens Axboe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox