64-bit data integrity field support
Subsystems (5)
Keith Busch
maintainerv2 cover 64-bit data integrity field support
The NVM Express protocol added enhancements to the data integrity field formats beyond the T10 defined protection information. A detailed description of the new formats can be found in the NVMe's NVM Command Set Specification, section 5.2, available at:
https://nvmexpress.org/wp-content/uploads/NVM-Command-Set-Specification-1.0b-2021.12.18-Ratified.pdf
This series implements one possible new format: the CRC64 guard with 48-bit reference tags. This does not add support for the variable "storage tag" field, or any potential hardware acceleration.
Changes since RFC v1:
- Generated the reflected CRC table and cacluated CRC accordingly instead of reflecting the input/output (Eric Biggers, patch 3)
- Fixed Kconfig.debug dependency for CRC tests (patch 4)
- Fixed endian conversion sparse error (patch 7).
- Added support for PRACT (Klaus Jensen, patch 7)
Keith Busch (7):
block: support pi with extended metadata
nvme: allow integrity on extended metadata formats
lib: add rocksoft model crc64
lib: add crc64 tests
asm-generic: introduce be48 unaligned accessors
block: add pi for nvme enhanced integrity
nvme: add support for enhanced metadata
block/Kconfig | 1 + block/bio-integrity.c | 1 + block/t10-pi.c | 198 +++++++++++++++++++++++++++++++- drivers/nvme/host/core.c | 167 ++++++++++++++++++++++----- drivers/nvme/host/nvme.h | 4 +- include/asm-generic/unaligned.h | 26 +++++ include/linux/blk-integrity.h | 1 + include/linux/crc64.h | 2 + include/linux/nvme.h | 53 ++++++++- include/linux/t10-pi.h | 20 ++++ lib/Kconfig.debug | 4 + lib/Makefile | 1 + lib/crc64.c | 26 +++++ lib/gen_crc64table.c | 51 ++++++-- lib/test_crc64.c | 68 +++++++++++ 15 files changed, 576 insertions(+), 47 deletions(-) create mode 100644 lib/test_crc64.c
Signature · 1 line
2.25.4
Keith Busch
maintainerPATCH v2 1/7 block: support pi with extended metadata
The nvme spec allows protection information formats with metadata extending beyond the pi field. Use the actual size of the metadata field for incrementing the protection buffer.
--- block/bio-integrity.c | 1 + block/t10-pi.c | 4 ++-- include/linux/blk-integrity.h | 1 + 3 files changed, 4 insertions(+), 2 deletions(-)
block/bio-integrity.c +1 -0
@@ -165,6 +165,7 @@ static blk_status_t bio_integrity_process(struct bio *bio, iter.disk_name = bio->bi_bdev->bd_disk->disk_name; iter.interval =1 << bi->interval_exp; + iter.tuple_size = bi->tuple_size; iter.seed = proc_iter->bi_sector; iter.prot_buf =bvec_virt (bip->bip_vec);
block/t10-pi.c +2 -2
@@ -44,7 +44,7 @@ static blk_status_t t10_pi_generate(struct blk_integrity_iter *iter, pi->ref_tag =0 ; iter->data_buf += iter->interval; - iter->prot_buf +=sizeof (struct t10_pi_tuple ); + iter->prot_buf += iter->tuple_size; iter->seed++; }
@@ -93,7 +93,7 @@ static blk_status_t t10_pi_verify(struct blk_integrity_iter *iter, next: iter->data_buf += iter->interval; - iter->prot_buf +=sizeof (struct t10_pi_tuple ); + iter->prot_buf += iter->tuple_size; iter->seed++; }
include/linux/blk-integrity.h +1 -0
@@ -19,6 +19,7 @@ struct blk_integrity_iter {sector_t seed;unsigned int data_size;unsigned short interval; +unsigned char tuple_size;const char *disk_name; };
Signature · 1 line
2.25.4
Re: [PATCHv2 1/7] block: support pi with extended metadata
Keith,
Quoted 2 lines
The nvme spec allows protection information formats with metadata extending beyond the pi field.
This may be true but it seems the rationale for the patch in the context of this series is to enable PI metadata bigger than t10_pi_tuple?
Signature · 1 line
Martin K. Petersen Oracle Linux Engineering
Re: [PATCHv2 1/7] block: support pi with extended metadata
In reply to Keith BuschQuoted 11 lines · Keith Busch
The nvme spec allows protection information formats with metadata extending beyond the pi field. Use the actual size of the metadata field for incrementing the protection buffer.
Signed-off-by Keith Busch <[email protected]>--- block/bio-integrity.c | 1 + block/t10-pi.c | 4 ++-- include/linux/blk-integrity.h | 1 + 3 files changed, 4 insertions(+), 2 deletions(-)
Cheers,
Hannes
Signature · 4 lines
Dr. Hannes Reinecke Kernel Storage Architect [email protected] +49 911 74053 688 SUSE Software Solutions Germany GmbH, Maxfeldstr. 5, 90409 Nürnberg HRB 36809 (AG Nürnberg), GF: Felix Imendörffer
Keith Busch
maintainerPATCH v2 2/7 nvme: allow integrity on extended metadata formats
In reply to Keith BuschThe block integrity subsystem knows how to construct protection information buffers with metadata beyond the protection information fields. Remove the driver restriction.
Note, this can only work if the PI field appears first in the metadata, as the integrity subsystem doesn't calculate guard tags on preceding metadata.
--- drivers/nvme/host/core.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
drivers/nvme/host/core.c +2 -5
@@ -1726,12 +1726,9 @@ static int nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id) {struct nvme_ctrl *ctrl = ns->ctrl; -/* -* The PI implementation requires the metadata size to be equal to the -* t10 pi tuple size. -*/ ns->ms =le16_to_cpu (id->lbaf[id->flbas &NVME_NS_FLBAS_LBA_MASK ].ms); -if (ns->ms ==sizeof (struct t10_pi_tuple )) +if (id->dps &NVME_NS_DPS_PI_FIRST || + ns->ms ==sizeof (struct t10_pi_tuple )) ns->pi_type = id->dps &NVME_NS_DPS_PI_MASK ;else ns->pi_type =0 ;
Signature · 1 line
2.25.4
Re: [PATCHv2 2/7] nvme: allow integrity on extended metadata formats
Keith,
Quoted 7 lines
The block integrity subsystem knows how to construct protection information buffers with metadata beyond the protection information fields. Remove the driver restriction.
Note, this can only work if the PI field appears first in the metadata, as the integrity subsystem doesn't calculate guard tags on preceding metadata.
Signature · 1 line
Martin K. Petersen Oracle Linux Engineering
Re: [PATCHv2 2/7] nvme: allow integrity on extended metadata formats
In reply to Keith BuschQuoted 4 lines · Keith Busch
The block integrity subsystem knows how to construct protection information buffers with metadata beyond the protection information fields. Remove the driver restriction.
Quoted 9 lines
Note, this can only work if the PI field appears first in the metadata, as the integrity subsystem doesn't calculate guard tags on preceding metadata.
Signed-off-by Keith Busch <[email protected]>--- drivers/nvme/host/core.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
Cheers,
Hannes
Signature · 4 lines
Dr. Hannes Reinecke Kernel Storage Architect [email protected] +49 911 74053 688 SUSE Software Solutions Germany GmbH, Maxfeldstr. 5, 90409 Nürnberg HRB 36809 (AG Nürnberg), GF: Felix Imendörffer
Keith Busch
maintainerPATCH v2 3/7 lib: add rocksoft model crc64
In reply to Keith BuschThe NVM Express specification extended data integrity fields to 64 bits using the Rocksoft^TM parameters. Add the poly to the crc64 table generation, and provide a library routine implementing the algorithm.
The Rocksoft 64-bit CRC model parameters are as follows:
Poly: 0xAD93D23594C93659
Initial value: 0xFFFFFFFFFFFFFFFF
Reflected Input: True
Reflected Output: True
Xor Final: 0xFFFFFFFFFFFFFFFFSince this model used reflected bits, the implementation generates the reflected table so the result is ordered consistently.
---v1->v2:
Generate a reflected table for the polynomial so that the inputs and outputs don't need to be reflected during calculating the CRC
include/linux/crc64.h | 2 ++ lib/crc64.c | 26 ++++++++++++++++++++++ lib/gen_crc64table.c | 51 +++++++++++++++++++++++++++++++++---------- 3 files changed, 68 insertions(+), 11 deletions(-)
include/linux/crc64.h +2 -0
@@ -8,4 +8,6 @@#include <linux/types.h> u64 __pure crc64_be (u64 crc,const void *p,size_t len); +u64 __pure crc64_rocksoft (u64 crc,const void *p,size_t len); +#endif /* _LINUX_CRC64_H */
lib/crc64.c +26 -0
@@ -22,6 +22,13 @@* x^24 + x^23 + x^22 + x^21 + x^19 + x^17 + x^13 + x^12 + x^10 + x^9 + * x^7 + x^4 + x + 1 * +* crc64rocksoft[256] table is from the Rocksoft specification polynomial +* defined as, +* +* x^64 + x^63 + x^61 + x^59 + x^58 + x^56 + x^55 + x^52 + x^49 + x^48 + x^47 + +* x^46 + x^44 + x^41 + x^37 + x^36 + x^34 + x^32 + x^31 + x^28 + x^26 + x^23 + +* x^22 + x^19 + x^16 + x^13 + x^12 + x^10 + x^9 + x^6 + x^4 + x^3 + 1 +* * Copyright 2018 SUSE Linux. * Author: Coly Li <[email protected]> */
@@ -55,3 +62,22 @@ u64 __pure crc64_be(u64 crc, const void *p, size_t len)return crc; }EXPORT_SYMBOL_GPL (crc64_be); + +/** +* crc64_rocksoft - Calculate bitwise Rocksoft CRC64 +* @crc: seed value for computation. (u64)~0 for a new CRC calculation, or the +* previous crc64 value if computing incrementally. +* @p: pointer to buffer over which CRC64 is run +* @len: length of buffer @p +*/ +u64 __pure crc64_rocksoft (u64 crc,const void *p,size_t len) +{ +const unsigned char *_p = p; +size_t i; + +for (i =0 ; i < len; i++) + crc = (crc >>8 ) ^ crc64rocksofttable[(crc &0xff ) ^ *_p++]; + +return crc ^ (u64 )~0 ; +} +EXPORT_SYMBOL_GPL (crc64_rocksoft);
lib/gen_crc64table.c +40 -11
85 lines not on this page · raw message
Signature · 1 line
2.25.4
Re: [PATCHv2 3/7] lib: add rocksoft model crc64
Keith,
Quoted 3 lines
The NVM Express specification extended data integrity fields to 64 bits using the Rocksoft^TM parameters. Add the poly to the crc64 table generation, and provide a library routine implementing the algorithm.
Looks OK to me.
Signature · 1 line
Martin K. Petersen Oracle Linux Engineering
Re: [PATCHv2 3/7] lib: add rocksoft model crc64
In reply to Keith BuschQuoted 11 lines · Keith Busch
The NVM Express specification extended data integrity fields to 64 bits using the Rocksoft^TM parameters. Add the poly to the crc64 table generation, and provide a library routine implementing the algorithm.
The Rocksoft 64-bit CRC model parameters are as follows:
Poly: 0xAD93D23594C93659 Initial value: 0xFFFFFFFFFFFFFFFF Reflected Input: True Reflected Output: True Xor Final: 0xFFFFFFFFFFFFFFFF
Quoted 8 lines
Since this model used reflected bits, the implementation generates the reflected table so the result is ordered consistently.
Cc Eric Biggers <[email protected]>Signed-off-by Keith Busch <[email protected]>---
v1->v2:
Cheers,
Hannes
Signature · 4 lines
Dr. Hannes Reinecke Kernel Storage Architect [email protected] +49 911 74053 688 SUSE Software Solutions Germany GmbH, Maxfeldstr. 5, 90409 Nürnberg HRB 36809 (AG Nürnberg), GF: Felix Imendörffer
Keith Busch
maintainerPATCH v2 4/7 lib: add crc64 tests
In reply to Keith BuschProvide a module to test the rocksoft crc64 calculations with well known inputs and exepected values.
---v1->v2:
Fixed Kconfig dependency
lib/Kconfig.debug | 4 +++ lib/Makefile | 1 + lib/test_crc64.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+) create mode 100644 lib/test_crc64.c
lib/Kconfig.debug +4 -0
@@ -2214,6 +2214,10 @@ config TEST_UUID config TEST_XARRAY tristate "Test the XArray code at runtime" +config TEST_CRC64 + depends on CRC64 + tristate "Test the crc64 code at runtime" + config TEST_OVERFLOW tristate "Test check_*_overflow() functions at runtime"
lib/Makefile +1 -0
@@ -103,6 +103,7 @@ obj-$(CONFIG_TEST_HMM) += test_hmm.o obj-$(CONFIG_TEST_FREE_PAGES) += test_free_pages.o obj-$(CONFIG_KPROBES_SANITY_TEST) += test_kprobes.o obj-$(CONFIG_TEST_REF_TRACKER) += test_ref_tracker.o +obj-$(CONFIG_TEST_CRC64) += test_crc64.o # # CFLAGS for compiling floating point code inside the kernel. x86/Makefile turns # off the generation of FPU/SSE* instructions for kernel proper but FPU_FLAGS
lib/test_crc64.c new file +68 -0
68 lines not on this page · raw message
Signature · 1 line
2.25.4
Re: [PATCHv2 4/7] lib: add crc64 tests
Keith,
Quoted 2 lines
Provide a module to test the rocksoft crc64 calculations with well known inputs and exepected values.
Signature · 1 line
Martin K. Petersen Oracle Linux Engineering
Re: [PATCHv2 4/7] lib: add crc64 tests
In reply to Keith BuschQuoted 7 lines · Keith Busch
Provide a module to test the rocksoft crc64 calculations with well known inputs and exepected values.
Signed-off-by Keith Busch <[email protected]>---
v1->v2:
Quoted 8 lines
Fixed
Kconfigdependencylib/Kconfig.debug | 4 +++ lib/Makefile | 1 + lib/test_crc64.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+)create mode 100644
lib/test_crc64.c
Cheers,
Hannes
Signature · 4 lines
Dr. Hannes Reinecke Kernel Storage Architect [email protected] +49 911 74053 688 SUSE Software Solutions Germany GmbH, Maxfeldstr. 5, 90409 Nürnberg HRB 36809 (AG Nürnberg), GF: Felix Imendörffer
Keith Busch
maintainerPATCH v2 5/7 asm-generic: introduce be48 unaligned accessors
In reply to Keith BuschThe NVMe protocol extended the data integrity fields with unaligned 48-bit reference tags. Provide some helper accessors in preparation for these.
--- include/asm-generic/unaligned.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
include/asm-generic/unaligned.h +26 -0
@@ -126,4 +126,30 @@ static inline void put_unaligned_le24(const u32 val, void *p)__put_unaligned_le24 (val, p); } +static inline void __put_unaligned_be48 (const u64 val,__u8 *p) +{ + *p++ = val >>40 ; + *p++ = val >>32 ; + *p++ = val >>24 ; + *p++ = val >>16 ; + *p++ = val >>8 ; + *p++ = val; +} + +static inline void put_unaligned_be48 (const u64 val,void *p) +{ +__put_unaligned_be48 (val, p); +} + +static inline u64 __get_unaligned_be48 (const u8 *p) +{ +return (u64 )p[0 ] <<40 | (u64 )p[1 ] <<32 | p[2 ] <<24 | + p[3 ] <<16 | p[4 ] <<8 | p[5 ]; +} + +static inline u64 get_unaligned_be48 (const void *p) +{ +return __get_unaligned_be48 (p); +} +#endif /* __ASM_GENERIC_UNALIGNED_H */
Signature · 1 line
2.25.4
Re: [PATCHv2 5/7] asm-generic: introduce be48 unaligned accessors
Keith,
Quoted 3 lines
The NVMe protocol extended the data integrity fields with unaligned 48-bit reference tags. Provide some helper accessors in preparation for these.
Looks good. Needed this a few times in the past.
Signature · 1 line
Martin K. Petersen Oracle Linux Engineering
Re: [PATCHv2 5/7] asm-generic: introduce be48 unaligned accessors
In reply to Keith BuschQuoted 10 lines · Keith Busch
The NVMe protocol extended the data integrity fields with unaligned 48-bit reference tags. Provide some helper accessors in preparation for these.
Acked-by Arnd Bergmann <[email protected]>Signed-off-by Keith Busch <[email protected]>--- include/asm-generic/unaligned.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
Hehe.
Cheers,
Hannes
Signature · 4 lines
Dr. Hannes Reinecke Kernel Storage Architect [email protected] +49 911 74053 688 SUSE Software Solutions Germany GmbH, Maxfeldstr. 5, 90409 Nürnberg HRB 36809 (AG Nürnberg), GF: Felix Imendörffer
Keith Busch
maintainerPATCH v2 6/7 block: add pi for nvme enhanced integrity
In reply to Keith BuschThe NVMe specification defines larger data integrity formats beyond the t10 tuple. Add support for the specification defined CRC64 formats, assuming the reference tag does not need to be split with the "storage tag".
--- block/Kconfig | 1 + block/t10-pi.c | 194 +++++++++++++++++++++++++++++++++++++++++ include/linux/t10-pi.h | 20 +++++ 3 files changed, 215 insertions(+)
block/Kconfig +1 -0
@@ -75,6 +75,7 @@ config BLK_DEV_INTEGRITY_T10 tristate depends on BLK_DEV_INTEGRITY select CRC_T10DIF + select CRC64 config BLK_DEV_ZONED bool "Zoned block device support"
block/t10-pi.c +194 -0
206 lines not on this page · raw message
include/linux/t10-pi.h +20 -0
@@ -53,4 +53,24 @@ extern const struct blk_integrity_profile t10_pi_type1_ip;extern const struct blk_integrity_profile t10_pi_type3_crc;extern const struct blk_integrity_profile t10_pi_type3_ip; +struct nvme_crc64_pi_tuple { +__be64 guard_tag; +__be16 app_tag; +__u8 ref_tag[6 ]; +}; + +static inline u64 nvme_pi_extended_ref_tag (struct request *rq) +{ +unsigned int shift =ilog2 (queue_logical_block_size (rq->q)); + +#ifdef CONFIG_BLK_DEV_INTEGRITY +if (rq->q->integrity.interval_exp) + shift = rq->q->integrity.interval_exp; +#endif +return blk_rq_pos (rq) >> (shift -SECTOR_SHIFT ) &0xffffffffffffull ; +} + +extern const struct blk_integrity_profile nvme_pi_type1_crc64; +extern const struct blk_integrity_profile nvme_pi_type3_crc64; +#endif
Signature · 1 line
2.25.4
Re: [PATCHv2 6/7] block: add pi for nvme enhanced integrity
Keith,
This all looks pretty good to me. Only nit I have is:
block/t10-pi.c const struct blk_integrity_profile t10_pi_type3_ip = { · line 372
Quoted 9 lines
block/t10-pi.c +9
-0+static blk_status_t nvme_pi_type1_verify_crc (struct blk_integrity_iter *iter) +{ +return nvme_crc64_verify (iter,T10_PI_TYPE1_PROTECTION ); +} + +static blk_status_t nvme_pi_type1_generate_crc (struct blk_integrity_iter *iter) +{ +return nvme_crc64_generate (iter,T10_PI_TYPE1_PROTECTION ); +}
Since we will definitely need to support the CRC32C variants, the nvme_pi_type1_ prefix is a bit too generic. Wish we had gone with Type 4 and 5 like I originally proposed in SCSI. Not a big fan of this "almost exactly like T10 Type 1 except for all these differences" situation that NVMe ended up with.
Anyway. So I think the NVMe-specific format helpers need to at the very least capture that they are for the CRC64 case.
Other than that it looks OK.
Signature · 1 line
Martin K. Petersen Oracle Linux Engineering
Re: [PATCHv2 6/7] block: add pi for nvme enhanced integrity
In reply to Keith BuschQuoted 5 lines · Keith Busch
The NVMe specification defines larger data integrity formats beyond the t10 tuple. Add support for the specification defined CRC64 formats, assuming the reference tag does not need to be split with the "storage tag".
Quoted 8 lines
Cc "Martin K. Petersen" <[email protected]>Signed-off-by Keith Busch <[email protected]>--- block/Kconfig | 1 + block/t10-pi.c | 194 +++++++++++++++++++++++++++++++++++++++++ include/linux/t10-pi.h | 20 +++++ 3 files changed, 215 insertions(+)
Cheers,
Hannes
Signature · 4 lines
Dr. Hannes Reinecke Kernel Storage Architect [email protected] +49 911 74053 688 SUSE Software Solutions Germany GmbH, Maxfeldstr. 5, 90409 Nürnberg HRB 36809 (AG Nürnberg), GF: Felix Imendörffer
Re: [PATCHv2 6/7] block: add pi for nvme enhanced integrity
In reply to Keith Buschblock/t10-pi.c const struct blk_integrity_profile t10_pi_type3_ip = { · line 334
Quoted 2 lines · Keith Busch
block/t10-pi.c +2
-0+ ref =get_unaligned_be48 (pi->ref_tag); + seed = iter->seed &0xffffffffffffull ;
The "& 0xffffffffffffull" operation occurs three times in this patch. Has it been considered to introduce a lower_48_bits() function?
Thanks,
Bart.
Keith Busch
maintainerPATCH v2 7/7 nvme: add support for enhanced metadata
In reply to Keith BuschNVM Express ratified TP 4069 defines new protection information formats. Implement support for the CRC64 guard tags.
Since the block layer doesn't support variable length reference tags, driver support for the Storage Tag space is not supported at this time.
---v1->v2:
Added support for PRACT
Fixed endian conversion
drivers/nvme/host/core.c | 164 +++++++++++++++++++++++++++++++++------ drivers/nvme/host/nvme.h | 4 +- include/linux/nvme.h | 53 +++++++++++-- 3 files changed, 190 insertions(+), 31 deletions(-)
drivers/nvme/host/core.c +140 -24
@@ -882,6 +882,30 @@ static blk_status_t nvme_setup_discard(struct nvme_ns *ns, struct request *req,return BLK_STS_OK ; } +static inline void nvme_set_ref_tag (struct nvme_ns *ns,struct nvme_command *cmnd, +struct request *req) +{ +u32 upper, lower; +u64 ref48; + +/* both rw and write zeroes share the same reftag format */ +switch (ns->guard_type) { +case NVME_NVM_NS_16B_GUARD : + cmnd->rw.reftag =cpu_to_le32 (t10_pi_ref_tag (req)); +break ; +case NVME_NVM_NS_64B_GUARD : + ref48 =nvme_pi_extended_ref_tag (req); + lower =lower_32_bits (ref48); + upper =upper_32_bits (ref48); + + cmnd->rw.reftag =cpu_to_le32 (lower); + cmnd->rw.cdw3 =cpu_to_le32 (upper); +break ; +default : +break ; + } +} +static inline blk_status_t nvme_setup_write_zeroes (struct nvme_ns *ns,struct request *req,struct nvme_command *cmnd) {
@@ -903,8 +927,7 @@ static inline blk_status_t nvme_setup_write_zeroes(struct nvme_ns *ns,switch (ns->pi_type) {case NVME_NS_DPS_PI_TYPE1 :case NVME_NS_DPS_PI_TYPE2 : - cmnd->write_zeroes.reftag = -cpu_to_le32 (t10_pi_ref_tag (req)); +nvme_set_ref_tag (ns, cmnd, req);break ; } }
@@ -931,7 +954,8 @@ static inline blk_status_t nvme_setup_rw(struct nvme_ns *ns, cmnd->rw.opcode = op; cmnd->rw.flags =0 ; cmnd->rw.nsid =cpu_to_le32 (ns->head->ns_id); - cmnd->rw.rsvd2 =0 ; + cmnd->rw.cdw2 =0 ; + cmnd->rw.cdw3 =0 ; cmnd->rw.metadata =0 ; cmnd->rw.slba =cpu_to_le64 (nvme_sect_to_lba (ns,blk_rq_pos (req))); cmnd->rw.length =cpu_to_le16 ((blk_rq_bytes (req) >> ns->lba_shift) -1 );
@@ -965,7 +989,7 @@ static inline blk_status_t nvme_setup_rw(struct nvme_ns *ns,NVME_RW_PRINFO_PRCHK_REF ;if (op == nvme_cmd_zone_append) control |=NVME_RW_APPEND_PIREMAP ; - cmnd->rw.reftag =cpu_to_le32 (t10_pi_ref_tag (req)); +nvme_set_ref_tag (ns, cmnd, req);break ; } }
@@ -1619,33 +1643,58 @@ int nvme_getgeo(struct block_device *bdev, struct hd_geometry *geo) }#ifdef CONFIG_BLK_DEV_INTEGRITY -static void nvme_init_integrity (struct gendisk *disk,u16 ms,u8 pi_type, +static void nvme_init_integrity (struct gendisk *disk,struct nvme_ns *ns,u32 max_integrity_segments) {struct blk_integrity integrity = { }; -switch (pi_type) { +switch (ns->pi_type) {case NVME_NS_DPS_PI_TYPE3 : - integrity.profile = &t10_pi_type3_crc; - integrity.tag_size =sizeof (u16) +sizeof (u32); - integrity.flags |=BLK_INTEGRITY_DEVICE_CAPABLE ; +switch (ns->guard_type) { +case NVME_NVM_NS_16B_GUARD : + integrity.profile = &t10_pi_type3_crc; + integrity.tag_size =sizeof (u16) +sizeof (u32); + integrity.flags |=BLK_INTEGRITY_DEVICE_CAPABLE ; +break ; +case NVME_NVM_NS_64B_GUARD : + integrity.profile = &nvme_pi_type1_crc64; + integrity.tag_size =sizeof (u16) +6 ; + integrity.flags |=BLK_INTEGRITY_DEVICE_CAPABLE ; +break ; +default : + integrity.profile =NULL ; +break ; + }break ;case NVME_NS_DPS_PI_TYPE1 :case NVME_NS_DPS_PI_TYPE2 : - integrity.profile = &t10_pi_type1_crc; - integrity.tag_size =sizeof (u16); - integrity.flags |=BLK_INTEGRITY_DEVICE_CAPABLE ; +switch (ns->guard_type) { +case NVME_NVM_NS_16B_GUARD : + integrity.profile = &t10_pi_type1_crc; + integrity.tag_size =sizeof (u16); + integrity.flags |=BLK_INTEGRITY_DEVICE_CAPABLE ; +break ; +case NVME_NVM_NS_64B_GUARD : + integrity.profile = &nvme_pi_type1_crc64; + integrity.tag_size =sizeof (u16); + integrity.flags |=BLK_INTEGRITY_DEVICE_CAPABLE ; +break ; +default : + integrity.profile =NULL ; +break ; + }break ;default : integrity.profile =NULL ;break ; } - integrity.tuple_size = ms; + + integrity.tuple_size = ns->ms;blk_integrity_register (disk, &integrity);blk_queue_max_integrity_segments (disk->queue, max_integrity_segments); }#else -static void nvme_init_integrity (struct gendisk *disk,u16 ms,u8 pi_type, +static void nvme_init_integrity (struct gendisk *disk,struct nvme_ns *ns,u32 max_integrity_segments) { }
@@ -1722,17 +1771,75 @@ static int nvme_setup_streams_ns(struct nvme_ctrl *ctrl, struct nvme_ns *ns,return 0 ; } -static int nvme_configure_metadata (struct nvme_ns *ns,struct nvme_id_ns *id) +static int nvme_init_ms (struct nvme_ns *ns,struct nvme_id_ns *id) { +bool first = id->dps &NVME_NS_DPS_PI_FIRST ; +unsigned lbaf =nvme_lbaf_index (id->flbas);struct nvme_ctrl *ctrl = ns->ctrl; +struct nvme_command c = { }; +struct nvme_id_ns_nvm *nvm; +int ret =0 ; +u32 elbaf; + + ns->pi_size =0 ; + ns->ms =le16_to_cpu (id->lbaf[lbaf].ms); +if (!(ctrl->ctratt &NVME_CTRL_ATTR_ELBAS )) { + ns->pi_size =sizeof (struct t10_pi_tuple ); + ns->guard_type =NVME_NVM_NS_16B_GUARD ; + goto set_pi; + } - ns->ms =le16_to_cpu (id->lbaf[id->flbas &NVME_NS_FLBAS_LBA_MASK ].ms); -if (id->dps &NVME_NS_DPS_PI_FIRST || - ns->ms ==sizeof (struct t10_pi_tuple )) + nvm =kzalloc (sizeof (*nvm),GFP_KERNEL ); +if (!nvm) +return -ENOMEM ; + + c.identify.opcode = nvme_admin_identify; + c.identify.nsid =cpu_to_le32 (ns->head->ns_id); + c.identify.cns =NVME_ID_CNS_CS_NS ; + c.identify.csi =NVME_CSI_NVM ; + + ret =nvme_submit_sync_cmd (ns->ctrl->admin_q, &c, nvm,sizeof (*nvm)); +if (ret) + goto free_data; + + elbaf =le32_to_cpu (nvm->elbaf[lbaf]); + +/* no support for storage tag formats right now */ +if (nvme_elbaf_sts (elbaf)) + goto free_data; + + ns->guard_type =nvme_elbaf_guard_type (elbaf); +switch (ns->guard_type) { +case NVME_NVM_NS_64B_GUARD : + ns->pi_size =sizeof (struct nvme_crc64_pi_tuple ); +break ; +case NVME_NVM_NS_16B_GUARD : + ns->pi_size =sizeof (struct t10_pi_tuple ); +break ; +default : +break ; + } + +free_data: +kfree (nvm); +set_pi: +if (ns->pi_size && (first || ns->ms == ns->pi_size)) ns->pi_type = id->dps &NVME_NS_DPS_PI_MASK ;else ns->pi_type =0 ; +return ret; +} + +static int nvme_configure_metadata (struct nvme_ns *ns,struct nvme_id_ns *id) +{ +struct nvme_ctrl *ctrl = ns->ctrl; +int ret; + + ret =nvme_init_ms (ns, id); +if (ret) +return ret; + ns->features &= ~(NVME_NS_METADATA_SUPPORTED |NVME_NS_EXT_LBAS );if (!ns->ms || !(ctrl->ops->flags &NVME_F_METADATA_SUPPORTED ))return 0 ;
@@ -1850,7 +1957,7 @@ static void nvme_update_disk_info(struct gendisk *disk,if (ns->ms) {if (IS_ENABLED (CONFIG_BLK_DEV_INTEGRITY ) && (ns->features &NVME_NS_METADATA_SUPPORTED )) -nvme_init_integrity (disk, ns->ms, ns->pi_type, +nvme_init_integrity (disk, ns, ns->ctrl->max_integrity_segments);else if (!nvme_ns_has_pi (ns)) capacity =0 ;
@@ -1905,7 +2012,7 @@ static void nvme_set_chunk_sectors(struct nvme_ns *ns, struct nvme_id_ns *id)static int nvme_update_ns_info (struct nvme_ns *ns,struct nvme_id_ns *id) { -unsigned lbaf = id->flbas &NVME_NS_FLBAS_LBA_MASK ; +unsigned lbaf =nvme_lbaf_index (id->flbas);int ret;blk_mq_freeze_queue (ns->disk->queue);
@@ -2252,20 +2359,27 @@ static int nvme_configure_timestamp(struct nvme_ctrl *ctrl)return ret; } -static int nvme_configure_acre (struct nvme_ctrl *ctrl) +static int nvme_configure_host_options (struct nvme_ctrl *ctrl) {struct nvme_feat_host_behavior *host; +u8 acre =0 , lbafee =0 ;int ret;/* Don't bother enabling the feature if retry delay is not reported */ -if (!ctrl->crdt[0 ]) +if (ctrl->crdt[0 ]) + acre =NVME_ENABLE_ACRE ; +if (ctrl->ctratt &NVME_CTRL_ATTR_ELBAS ) + lbafee =NVME_ENABLE_LBAFEE ; + +if (!acre && !lbafee)return 0 ; host =kzalloc (sizeof (*host),GFP_KERNEL );if (!host)return 0 ; - host->acre =NVME_ENABLE_ACRE ; + host->acre = acre; + host->lbafee = lbafee; ret =nvme_set_features (ctrl,NVME_FEAT_HOST_BEHAVIOR ,0 , host,sizeof (*host),NULL );kfree (host);
@@ -3104,7 +3218,7 @@ int nvme_init_ctrl_finish(struct nvme_ctrl *ctrl)if (ret <0 )return ret; - ret =nvme_configure_acre (ctrl); + ret =nvme_configure_host_options (ctrl);if (ret <0 )return ret;
@@ -4725,12 +4839,14 @@ static inline void _nvme_check_size(void)BUILD_BUG_ON (sizeof (struct nvme_id_ctrl ) !=NVME_IDENTIFY_DATA_SIZE );BUILD_BUG_ON (sizeof (struct nvme_id_ns ) !=NVME_IDENTIFY_DATA_SIZE );BUILD_BUG_ON (sizeof (struct nvme_id_ns_zns ) !=NVME_IDENTIFY_DATA_SIZE ); +BUILD_BUG_ON (sizeof (struct nvme_id_ns_nvm ) !=NVME_IDENTIFY_DATA_SIZE );BUILD_BUG_ON (sizeof (struct nvme_id_ctrl_zns ) !=NVME_IDENTIFY_DATA_SIZE );BUILD_BUG_ON (sizeof (struct nvme_id_ctrl_nvm ) !=NVME_IDENTIFY_DATA_SIZE );BUILD_BUG_ON (sizeof (struct nvme_lba_range_type ) !=64 );BUILD_BUG_ON (sizeof (struct nvme_smart_log ) !=512 );BUILD_BUG_ON (sizeof (struct nvme_dbbuf ) !=64 );BUILD_BUG_ON (sizeof (struct nvme_directive_cmd ) !=64 ); +BUILD_BUG_ON (sizeof (struct nvme_feat_host_behavior ) !=512 ); }
drivers/nvme/host/nvme.h +3 -1
@@ -452,9 +452,11 @@ struct nvme_ns {int lba_shift;u16 ms; +u16 pi_size;u16 sgs;u32 sws;u8 pi_type; +u8 guard_type;#ifdef CONFIG_BLK_DEV_ZONED u64 zsze;#endif
@@ -477,7 +479,7 @@ struct nvme_ns {/* NVMe ns supports metadata actions by the controller (generate/strip) */ static inline bool nvme_ns_has_pi (struct nvme_ns *ns) { -return ns->pi_type && ns->ms ==sizeof (struct t10_pi_tuple ); +return ns->pi_type && ns->ms == ns->pi_size; }struct nvme_ctrl_ops {
include/linux/nvme.h +47 -6
105 lines not on this page · raw message
Signature · 1 line
2.25.4
Re: [PATCHv2 7/7] nvme: add support for enhanced metadata
Keith,
Quoted 2 lines
NVM Express ratified TP 4069 defines new protection information formats. Implement support for the CRC64 guard tags.
Looks fine.
Signature · 1 line
Martin K. Petersen Oracle Linux Engineering
Re: [PATCHv2 7/7] nvme: add support for enhanced metadata
In reply to Keith BuschQuoted 119 lines · Keith Busch
NVM Express ratified TP 4069 defines new protection information formats. Implement support for the CRC64 guard tags.
Since the block layer doesn't support variable length reference tags, driver support for the Storage Tag space is not supported at this time.
Signed-off-by Keith Busch <[email protected]>---
v1->v2:Added support for PRACT
Fixed endian conversion
drivers/nvme/host/core.c | 164 +++++++++++++++++++++++++++++++++------ drivers/nvme/host/nvme.h | 4 +- include/linux/nvme.h | 53 +++++++++++-- 3 files changed, 190 insertions(+), 31 deletions(-)drivers/nvme/host/core.c +45
-11@@ -882,6 +882,30 @@ static blk_status_t nvme_setup_discard(struct nvme_ns *ns, struct request *req,return BLK_STS_OK ; } +static inline void nvme_set_ref_tag (struct nvme_ns *ns,struct nvme_command *cmnd, +struct request *req) +{ +u32 upper, lower; +u64 ref48; + +/* both rw and write zeroes share the same reftag format */ +switch (ns->guard_type) { +case NVME_NVM_NS_16B_GUARD : + cmnd->rw.reftag =cpu_to_le32 (t10_pi_ref_tag (req)); +break ; +case NVME_NVM_NS_64B_GUARD : + ref48 =nvme_pi_extended_ref_tag (req); + lower =lower_32_bits (ref48); + upper =upper_32_bits (ref48); + + cmnd->rw.reftag =cpu_to_le32 (lower); + cmnd->rw.cdw3 =cpu_to_le32 (upper); +break ; +default : +break ; + } +} +static inline blk_status_t nvme_setup_write_zeroes (struct nvme_ns *ns,struct request *req,struct nvme_command *cmnd) {@@ -903,8 +927,7 @@ static inline blk_status_t nvme_setup_write_zeroes(struct nvme_ns *ns,switch (ns->pi_type) {case NVME_NS_DPS_PI_TYPE1 :case NVME_NS_DPS_PI_TYPE2 : - cmnd->write_zeroes.reftag = -cpu_to_le32 (t10_pi_ref_tag (req)); +nvme_set_ref_tag (ns, cmnd, req);break ; } }@@ -931,7 +954,8 @@ static inline blk_status_t nvme_setup_rw(struct nvme_ns *ns, cmnd->rw.opcode = op; cmnd->rw.flags =0 ; cmnd->rw.nsid =cpu_to_le32 (ns->head->ns_id); - cmnd->rw.rsvd2 =0 ; + cmnd->rw.cdw2 =0 ; + cmnd->rw.cdw3 =0 ; cmnd->rw.metadata =0 ; cmnd->rw.slba =cpu_to_le64 (nvme_sect_to_lba (ns,blk_rq_pos (req))); cmnd->rw.length =cpu_to_le16 ((blk_rq_bytes (req) >> ns->lba_shift) -1 );@@ -965,7 +989,7 @@ static inline blk_status_t nvme_setup_rw(struct nvme_ns *ns,NVME_RW_PRINFO_PRCHK_REF ;if (op == nvme_cmd_zone_append) control |=NVME_RW_APPEND_PIREMAP ; - cmnd->rw.reftag =cpu_to_le32 (t10_pi_ref_tag (req)); +nvme_set_ref_tag (ns, cmnd, req);break ; } }@@ -1619,33 +1643,58 @@ int nvme_getgeo(struct block_device *bdev, struct hd_geometry *geo) }#ifdef CONFIG_BLK_DEV_INTEGRITY -static void nvme_init_integrity (struct gendisk *disk,u16 ms,u8 pi_type, +static void nvme_init_integrity (struct gendisk *disk,struct nvme_ns *ns,u32 max_integrity_segments) {struct blk_integrity integrity = { }; -switch (pi_type) { +switch (ns->pi_type) {case NVME_NS_DPS_PI_TYPE3 : - integrity.profile = &t10_pi_type3_crc; - integrity.tag_size =sizeof (u16) +sizeof (u32); - integrity.flags |=BLK_INTEGRITY_DEVICE_CAPABLE ; +switch (ns->guard_type) { +case NVME_NVM_NS_16B_GUARD : + integrity.profile = &t10_pi_type3_crc; + integrity.tag_size =sizeof (u16) +sizeof (u32); + integrity.flags |=BLK_INTEGRITY_DEVICE_CAPABLE ; +break ; +case NVME_NVM_NS_64B_GUARD : + integrity.profile = &nvme_pi_type1_crc64; + integrity.tag_size =sizeof (u16) +6 ; + integrity.flags |=BLK_INTEGRITY_DEVICE_CAPABLE ; +break ; +default : + integrity.profile =NULL ; +break ; + }break ;case NVME_NS_DPS_PI_TYPE1 :case NVME_NS_DPS_PI_TYPE2 : - integrity.profile = &t10_pi_type1_crc; - integrity.tag_size =sizeof (u16);
drivers/nvme/host/core.c int nvme_getgeo(struct block_device *bdev, struct hd_geometry *geo) · line 1679
Quoted 10 lines
drivers/nvme/host/core.c +9
-1- integrity.flags |=BLK_INTEGRITY_DEVICE_CAPABLE ; +switch (ns->guard_type) { +case NVME_NVM_NS_16B_GUARD : + integrity.profile = &t10_pi_type1_crc; + integrity.tag_size =sizeof (u16); + integrity.flags |=BLK_INTEGRITY_DEVICE_CAPABLE ; +break ; +case NVME_NVM_NS_64B_GUARD : + integrity.profile = &nvme_pi_type1_crc64; + integrity.tag_size =sizeof (u16);
Is that correct? Shouldn't it be '8' like in the above case?
Quoted 153 lines
drivers/nvme/host/core.c +83
-11+ integrity.flags |=BLK_INTEGRITY_DEVICE_CAPABLE ; +break ; +default : + integrity.profile =NULL ; + break; + }break ;default : integrity.profile =NULL ;break ; } - integrity.tuple_size = ms; + + integrity.tuple_size = ns->ms;blk_integrity_register (disk, &integrity);blk_queue_max_integrity_segments (disk->queue, max_integrity_segments); }#else -static void nvme_init_integrity (struct gendisk *disk,u16 ms,u8 pi_type, +static void nvme_init_integrity (struct gendisk *disk,struct nvme_ns *ns,u32 max_integrity_segments) { }@@ -1722,17 +1771,75 @@ static int nvme_setup_streams_ns(struct nvme_ctrl *ctrl, struct nvme_ns *ns,return 0 ; } -static int nvme_configure_metadata (struct nvme_ns *ns,struct nvme_id_ns *id) +static int nvme_init_ms (struct nvme_ns *ns,struct nvme_id_ns *id) { +bool first = id->dps &NVME_NS_DPS_PI_FIRST ; +unsigned lbaf =nvme_lbaf_index (id->flbas);struct nvme_ctrl *ctrl = ns->ctrl; +struct nvme_command c = { }; +struct nvme_id_ns_nvm *nvm; +int ret =0 ; +u32 elbaf; + + ns->pi_size =0 ; + ns->ms =le16_to_cpu (id->lbaf[lbaf].ms); +if (!(ctrl->ctratt &NVME_CTRL_ATTR_ELBAS )) { + ns->pi_size =sizeof (struct t10_pi_tuple ); + ns->guard_type =NVME_NVM_NS_16B_GUARD ; + goto set_pi; + } - ns->ms =le16_to_cpu (id->lbaf[id->flbas &NVME_NS_FLBAS_LBA_MASK ].ms); -if (id->dps &NVME_NS_DPS_PI_FIRST || - ns->ms ==sizeof (struct t10_pi_tuple )) + nvm =kzalloc (sizeof (*nvm),GFP_KERNEL ); +if (!nvm) +return -ENOMEM ; + + c.identify.opcode = nvme_admin_identify; + c.identify.nsid =cpu_to_le32 (ns->head->ns_id); + c.identify.cns =NVME_ID_CNS_CS_NS ; + c.identify.csi =NVME_CSI_NVM ; + + ret =nvme_submit_sync_cmd (ns->ctrl->admin_q, &c, nvm,sizeof (*nvm)); +if (ret) + goto free_data; + + elbaf =le32_to_cpu (nvm->elbaf[lbaf]); + +/* no support for storage tag formats right now */ +if (nvme_elbaf_sts (elbaf)) + goto free_data; + + ns->guard_type =nvme_elbaf_guard_type (elbaf); +switch (ns->guard_type) { +case NVME_NVM_NS_64B_GUARD : + ns->pi_size =sizeof (struct nvme_crc64_pi_tuple ); +break ; +case NVME_NVM_NS_16B_GUARD : + ns->pi_size =sizeof (struct t10_pi_tuple ); +break ; +default : +break ; + } + +free_data: +kfree (nvm); +set_pi: +if (ns->pi_size && (first || ns->ms == ns->pi_size)) ns->pi_type = id->dps &NVME_NS_DPS_PI_MASK ;else ns->pi_type =0 ; +return ret; +} + +static int nvme_configure_metadata (struct nvme_ns *ns,struct nvme_id_ns *id) +{ +struct nvme_ctrl *ctrl = ns->ctrl; +int ret; + + ret =nvme_init_ms (ns, id); +if (ret) +return ret; + ns->features &= ~(NVME_NS_METADATA_SUPPORTED |NVME_NS_EXT_LBAS );if (!ns->ms || !(ctrl->ops->flags &NVME_F_METADATA_SUPPORTED ))return 0 ;@@ -1850,7 +1957,7 @@ static void nvme_update_disk_info(struct gendisk *disk,if (ns->ms) {if (IS_ENABLED (CONFIG_BLK_DEV_INTEGRITY ) && (ns->features &NVME_NS_METADATA_SUPPORTED )) -nvme_init_integrity (disk, ns->ms, ns->pi_type, +nvme_init_integrity (disk, ns, ns->ctrl->max_integrity_segments);else if (!nvme_ns_has_pi (ns)) capacity =0 ;@@ -1905,7 +2012,7 @@ static void nvme_set_chunk_sectors(struct nvme_ns *ns, struct nvme_id_ns *id)static int nvme_update_ns_info (struct nvme_ns *ns,struct nvme_id_ns *id) { -unsigned lbaf = id->flbas &NVME_NS_FLBAS_LBA_MASK ; +unsigned lbaf =nvme_lbaf_index (id->flbas);int ret;blk_mq_freeze_queue (ns->disk->queue);@@ -2252,20 +2359,27 @@ static int nvme_configure_timestamp(struct nvme_ctrl *ctrl)return ret; } -static int nvme_configure_acre (struct nvme_ctrl *ctrl) +static int nvme_configure_host_options (struct nvme_ctrl *ctrl) {struct nvme_feat_host_behavior *host; +u8 acre =0 , lbafee =0 ;int ret;/* Don't bother enabling the feature if retry delay is not reported */ -if (!ctrl->crdt[0 ]) +if (ctrl->crdt[0 ]) + acre =NVME_ENABLE_ACRE ; +if (ctrl->ctratt &NVME_CTRL_ATTR_ELBAS ) + lbafee =NVME_ENABLE_LBAFEE ; + +if (!acre && !lbafee)return 0 ; host =kzalloc (sizeof (*host),GFP_KERNEL );if (!host)return 0 ; - host->acre =NVME_ENABLE_ACRE ; + host->acre = acre; + host->lbafee = lbafee; ret =nvme_set_features (ctrl,NVME_FEAT_HOST_BEHAVIOR ,0 , host,sizeof (*host),NULL );kfree (host);
drivers/nvme/host/core.c int nvme_init_ctrl_finish(struct nvme_ctrl *ctrl) · line 3224
Quoted 8 lines
drivers/nvme/host/core.c +1
-1@@ -3104,7 +3218,7 @@ int nvme_init_ctrl_finish(struct nvme_ctrl *ctrl)if (ret <0 )return ret; - ret =nvme_configure_acre (ctrl); + ret =nvme_configure_host_options (ctrl);if (ret <0 )return ret;
This could be made into a separate patch, is it's not directly related to PI support.
Cheers,
Hannes
Signature · 4 lines
Dr. Hannes Reinecke Kernel Storage Architect [email protected] +49 911 74053 688 SUSE Software Solutions Germany GmbH, Maxfeldstr. 5, 90409 Nürnberg HRB 36809 (AG Nürnberg), GF: Felix Imendörffer
Keith Busch
maintainerRe: [PATCHv2 7/7] nvme: add support for enhanced metadata
Quoted 5 lines · Hannes Reinecke
drivers/nvme/host/core.c int nvme_getgeo(struct block_device *bdev, struct hd_geometry *geo)
Quoted 4 lines · Keith Busch
drivers/nvme/host/core.c +4
-0+ integrity.flags |=BLK_INTEGRITY_DEVICE_CAPABLE ; +break ; +case NVME_NVM_NS_64B_GUARD : + integrity.profile = &nvme_pi_type1_crc64
I just noticed this should be type3, not type1...
Quoted 16 lines
Quoted 16 lines
drivers/nvme/host/core.c +10
-3+ integrity.tag_size =sizeof (u16) +6 ; + integrity.flags |=BLK_INTEGRITY_DEVICE_CAPABLE ; +break ; +default : + integrity.profile =NULL ; +break ; + }break ;case NVME_NS_DPS_PI_TYPE1 :case NVME_NS_DPS_PI_TYPE2 : - integrity.profile = &t10_pi_type1_crc; - integrity.tag_size =sizeof (u16); - integrity.flags |=BLK_INTEGRITY_DEVICE_CAPABLE ; +switch (ns->guard_type) { +case NVME_NVM_NS_16B_GUARD : + integrity.profile = &t10_pi_type1_crc;
Quoted 8 lines
drivers/nvme/host/core.c int nvme_getgeo(struct block_device *bdev, struct hd_geometry *geo) · line 1679
Quoted 6 lines
drivers/nvme/host/core.c +6
-0+ integrity.tag_size =sizeof (u16); + integrity.flags |=BLK_INTEGRITY_DEVICE_CAPABLE ; +break ; +case NVME_NVM_NS_64B_GUARD : + integrity.profile = &nvme_pi_type1_crc64; + integrity.tag_size =sizeof (u16);Is that correct? Shouldn't it be '8' like in the above case?
For type1 and 2, I believe tag_size refers to the "application" tag, which is 2 bytes here.
The reason it is 8 bytes for type3 is because there is no ref tag, so that portion of the metadata becomes part of the opaque application tag_size.
Quoted 10 lines
drivers/nvme/host/core.c int nvme_init_ctrl_finish(struct nvme_ctrl *ctrl) · line 3222
Quoted 7 lines
drivers/nvme/host/core.c +1
-1@@ -3104,7 +3218,7 @@ int nvme_init_ctrl_finish(struct nvme_ctrl *ctrl)if (ret <0 )return ret; - ret =nvme_configure_acre (ctrl); + ret =nvme_configure_host_options (ctrl);if (ret <0 )return ret;This could be made into a separate patch, is it's not directly related to PI support.
Well, the driver can't read the new PI formats without enabling host supported features for it. Enabling the feature tells the controller we're going to check for it, so I don't think we could reasonably split this part into a prep patch from the part that sets up the PI formats.
Re: [PATCHv2 7/7] nvme: add support for enhanced metadata
Keith,
Quoted 2 lines
For type1 and 2, I believe
tag_sizerefers to the "application" tag, which is 2 bytes here.
Yep.
Quoted 3 lines
The reason it is 8 bytes for type3 is because there is no ref tag, so that portion of the metadata becomes part of the opaque application
tag_size.
Correct.
Signature · 1 line
Martin K. Petersen Oracle Linux Engineering
Re: [PATCHv2 7/7] nvme: add support for enhanced metadata
In reply to Keith BuschQuoted 2 lines · Keith Busch
Quoted 1 line · Hannes Reinecke
On 2/1/22 20:01, Keith Busch wrote:
[ .. ]
Quoted 10 lines
Quoted 10 lines
drivers/nvme/host/core.c int nvme_init_ctrl_finish(struct nvme_ctrl *ctrl) · line 3222
Quoted 7 lines
drivers/nvme/host/core.c +1
-1@@ -3104,7 +3218,7 @@ int nvme_init_ctrl_finish(struct nvme_ctrl *ctrl)if (ret <0 )return ret; - ret =nvme_configure_acre (ctrl); + ret =nvme_configure_host_options (ctrl);if (ret <0 )return ret;This could be made into a separate patch, is it's not directly related to PI support. >
Quoted 4 lines
Well, the driver can't read the new PI formats without enabling host supported features for it. Enabling the feature tells the controller we're going to check for it, so I don't think we could reasonably split this part into a prep patch from the part that sets up the PI formats.
Actually I was thinking about a patch renaming 'nvme_configure_acre' into 'nvme_configure_host_options', as _this_ really is independent. When mixed together with the PI stuff it's hard to track down from the commit message when it got changed.
Cheers,
Hannes
Signature · 4 lines
Dr. Hannes Reinecke Kernel Storage Architect [email protected] +49 911 74053 688 SUSE Software Solutions GmbH, Maxfeldstr. 5, 90409 Nürnberg HRB 36809 (AG Nürnberg), Geschäftsführer: Felix Imendörffer