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@xxxxxxxxxxx> --- drivers/nvme/host/core.c | 24 ++++++++++++++++++++++++ drivers/nvme/host/nvme.h | 1 + 2 files changed, 25 insertions(+) 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; -- 2.25.1