diff mbox series

[RFC,2/3] nvme: support integrity offload

Message ID 20250129140207.22718-3-joshi.k@samsung.com (mailing list archive)
State New
Headers show
Series Btrfs checksum offload | expand

Commit Message

Kanchan Joshi Jan. 29, 2025, 2:02 p.m. UTC
Register the integrity offload with the block layer if it is supported
by the device.

Serve incoming offload requests by setting PRACT and GUARD check.

Signed-off-by: Kanchan Joshi <joshi.k@samsung.com>
---
 drivers/nvme/host/core.c | 24 ++++++++++++++++++++++++
 drivers/nvme/host/nvme.h |  1 +
 2 files changed, 25 insertions(+)
diff mbox series

Patch

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index f4b8d6a0984a..1fae0a6a932e 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -984,6 +984,7 @@  static inline blk_status_t nvme_setup_rw(struct nvme_ns *ns,
 {
 	u16 control = 0;
 	u32 dsmgmt = 0;
+	u8  type;
 
 	if (req->cmd_flags & REQ_FUA)
 		control |= NVME_RW_FUA;
@@ -1022,7 +1023,21 @@  static inline blk_status_t nvme_setup_rw(struct nvme_ns *ns,
 				return BLK_STS_NOTSUPP;
 			control |= NVME_RW_PRINFO_PRACT;
 		}
+		if (req->cmd_flags & REQ_INTEGRITY_OFFLOAD) {
+			type = ns->head->pi_offload_type;
 
+			if (type == BLK_INTEGRITY_OFFLOAD_NONE ||
+			    (type == BLK_INTEGRITY_OFFLOAD_BUF &&
+			     !blk_integrity_rq(req))) {
+				WARN_ON_ONCE(1);
+				return BLK_STS_NOTSUPP;
+			}
+
+			control |= NVME_RW_PRINFO_PRACT |
+				   NVME_RW_PRINFO_PRCHK_GUARD;
+			/* skip redundant processing for offload */
+			goto out;
+		}
 		if (bio_integrity_flagged(req->bio, BIP_CHECK_GUARD))
 			control |= NVME_RW_PRINFO_PRCHK_GUARD;
 		if (bio_integrity_flagged(req->bio, BIP_CHECK_REFTAG)) {
@@ -1037,6 +1052,7 @@  static inline blk_status_t nvme_setup_rw(struct nvme_ns *ns,
 		}
 	}
 
+out:
 	cmnd->rw.control = cpu_to_le16(control);
 	cmnd->rw.dsmgmt = cpu_to_le32(dsmgmt);
 	return 0;
@@ -1846,6 +1862,14 @@  static bool nvme_init_integrity(struct nvme_ns_head *head,
 
 	bi->tuple_size = head->ms;
 	bi->pi_offset = info->pi_offset;
+	if (bi->csum_type != BLK_INTEGRITY_CSUM_NONE) {
+		if (head->ms == head->pi_size)
+			bi->offload_type = BLK_INTEGRITY_OFFLOAD_NO_BUF;
+		else
+			bi->offload_type = BLK_INTEGRITY_OFFLOAD_BUF;
+		head->pi_offload_type = bi->offload_type;
+	}
+
 	return true;
 }
 
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index 7be92d07430e..add04583b040 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -476,6 +476,7 @@  struct nvme_ns_head {
 	u16			pi_size;
 	u8			pi_type;
 	u8			guard_type;
+	u8			pi_offload_type;
 	struct list_head	entry;
 	struct kref		ref;
 	bool			shared;