dif: Add data offset to DIF context separately from start block address

Data offset are intended to correspond to DATAO in NVMe/TCP and
Buffer Offset in iSCSI.

Previously for iSCSI, buffer offset had been merged to start block
address, but passing buffer offset separately from start block address
clarifies the logic more.

On the other hand, for NVMe/TCP, passing DATAO separately from start
block address will be critically important because DATAO will bave any
alignment and will be necessary to use for not only reference tag
but also guard computation.

This patch adds data_offset to struct spdk_dif_ctx and adds it to the
parameters of spdk_dif_ctx_init(). ref_tag_offset is also added to struct
spdk_dif_ctx and it is computed by dividing data_offset by data_block_size
and is used to compute reference tag.

The next patch will use this change when getting DIF context in SCSI.

Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Change-Id: Id0e12ca9b1dc75d0589787520feb0c2ee0f844a5
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/457540
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
Shuhei Matsumoto 2019-06-04 14:52:24 +09:00 committed by Ben Walker
parent d9ec66dfb6
commit 73204fe2e5
10 changed files with 41 additions and 28 deletions

View File

@ -575,7 +575,7 @@ fio_extended_lba_setup_pi(struct spdk_fio_qpair *fio_qpair, struct io_u *io_u)
rc = spdk_dif_ctx_init(&fio_req->dif_ctx, extended_lba_size, md_size,
true, fio_qpair->md_start,
(enum spdk_dif_type)spdk_nvme_ns_get_pi_type(ns),
fio_qpair->io_flags, lba, g_spdk_apptag_mask, g_spdk_apptag, 0);
fio_qpair->io_flags, lba, g_spdk_apptag_mask, g_spdk_apptag, 0, 0);
if (rc != 0) {
fprintf(stderr, "Initialization of DIF context failed\n");
return rc;
@ -609,7 +609,7 @@ fio_separate_md_setup_pi(struct spdk_fio_qpair *fio_qpair, struct io_u *io_u)
rc = spdk_dif_ctx_init(&fio_req->dif_ctx, block_size, md_size,
false, fio_qpair->md_start,
(enum spdk_dif_type)spdk_nvme_ns_get_pi_type(ns),
fio_qpair->io_flags, lba, g_spdk_apptag_mask, g_spdk_apptag, 0);
fio_qpair->io_flags, lba, g_spdk_apptag_mask, g_spdk_apptag, 0, 0);
if (rc != 0) {
fprintf(stderr, "Initialization of DIF context failed\n");
return rc;

View File

@ -485,7 +485,7 @@ nvme_submit_io(struct perf_task *task, struct ns_worker_ctx *ns_ctx,
rc = spdk_dif_ctx_init(&task->dif_ctx, entry->block_size, entry->md_size,
entry->md_interleave, entry->pi_loc,
(enum spdk_dif_type)entry->pi_type, entry->io_flags,
lba, 0xFFFF, (uint16_t)entry->io_size_blocks, 0);
lba, 0xFFFF, (uint16_t)entry->io_size_blocks, 0, 0);
if (rc != 0) {
fprintf(stderr, "Initialization of DIF context failed\n");
exit(1);

View File

@ -92,6 +92,12 @@ struct spdk_dif_ctx {
/* Application tag mask */
uint16_t apptag_mask;
/* Byte offset from the start of the whole data buffer. */
uint32_t data_offset;
/* Offset to initial reference tag */
uint32_t ref_tag_offset;
/* Seed value for guard computation */
uint16_t guard_seed;
};
@ -127,6 +133,7 @@ struct spdk_dif_error {
* starting block address.
* \param apptag_mask Application tag mask.
* \param app_tag Application tag.
* \param data_offset Byte offset from the start of the whole data buffer.
* \param guard_seed Seed value for guard computation.
*
* \return 0 on success and negated errno otherwise.
@ -134,7 +141,7 @@ struct spdk_dif_error {
int spdk_dif_ctx_init(struct spdk_dif_ctx *ctx, uint32_t block_size, uint32_t md_size,
bool md_interleave, bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags,
uint32_t init_ref_tag, uint16_t apptag_mask, uint16_t app_tag,
uint16_t guard_seed);
uint32_t data_offset, uint16_t guard_seed);
/**
* Generate DIF for extended LBA payload.

View File

@ -527,7 +527,7 @@ void spdk_scsi_lun_free_io_channel(struct spdk_scsi_lun_desc *desc);
*
* \param lun Logical unit.
* \param cdb SCSI CDB.
* \param offset Offset in the payload.
* \param offset Byte offset in the payload.
* \param dif_ctx Output parameter which will contain initialized DIF context.
*
* \return true on success or false otherwise.

View File

@ -1631,7 +1631,7 @@ bdev_nvme_verify_pi_error(struct spdk_bdev_io *bdev_io)
rc = spdk_dif_ctx_init(&dif_ctx,
bdev->blocklen, bdev->md_len, bdev->md_interleave,
bdev->dif_is_head_of_md, bdev->dif_type, bdev->dif_check_flags,
bdev_io->u.bdev.offset_blocks, 0, 0, 0);
bdev_io->u.bdev.offset_blocks, 0, 0, 0, 0);
if (rc != 0) {
SPDK_ERRLOG("Initialization of DIF context failed\n");
return;

View File

@ -2164,7 +2164,7 @@ spdk_scsi_bdev_get_dif_ctx(struct spdk_bdev *bdev, uint8_t *cdb, uint32_t offset
spdk_bdev_is_dif_head_of_md(bdev),
spdk_bdev_get_dif_type(bdev),
dif_check_flags,
ref_tag, 0, 0, 0);
ref_tag, 0, 0, 0, 0);
return (rc == 0) ? true : false;
}

View File

@ -200,8 +200,10 @@ int
spdk_dif_ctx_init(struct spdk_dif_ctx *ctx, uint32_t block_size, uint32_t md_size,
bool md_interleave, bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags,
uint32_t init_ref_tag, uint16_t apptag_mask, uint16_t app_tag,
uint16_t guard_seed)
uint32_t data_offset, uint16_t guard_seed)
{
uint32_t data_block_size;
if (md_size < sizeof(struct spdk_dif)) {
SPDK_ERRLOG("Metadata size is smaller than DIF size.\n");
return -EINVAL;
@ -212,11 +214,13 @@ spdk_dif_ctx_init(struct spdk_dif_ctx *ctx, uint32_t block_size, uint32_t md_siz
SPDK_ERRLOG("Block size is smaller than DIF size.\n");
return -EINVAL;
}
data_block_size = block_size - md_size;
} else {
if (block_size == 0 || (block_size % 512) != 0) {
SPDK_ERRLOG("Zero block size is not allowed\n");
return -EINVAL;
}
data_block_size = block_size;
}
if (!_dif_type_is_valid(dif_type, dif_flags)) {
@ -232,6 +236,8 @@ spdk_dif_ctx_init(struct spdk_dif_ctx *ctx, uint32_t block_size, uint32_t md_siz
ctx->init_ref_tag = init_ref_tag;
ctx->apptag_mask = apptag_mask;
ctx->app_tag = app_tag;
ctx->data_offset = data_offset;
ctx->ref_tag_offset = data_offset / data_block_size;
ctx->guard_seed = guard_seed;
return 0;
@ -258,9 +264,9 @@ _dif_generate(void *_dif, uint16_t guard, uint32_t offset_blocks,
* remains the same as the initial reference tag.
*/
if (ctx->dif_type != SPDK_DIF_TYPE3) {
ref_tag = ctx->init_ref_tag + offset_blocks;
ref_tag = ctx->init_ref_tag + ctx->ref_tag_offset + offset_blocks;
} else {
ref_tag = ctx->init_ref_tag;
ref_tag = ctx->init_ref_tag + ctx->ref_tag_offset;
}
to_be32(&dif->ref_tag, ref_tag);
@ -420,9 +426,9 @@ _dif_verify(void *_dif, uint16_t guard, uint32_t offset_blocks,
* remains the same as the initial reference tag.
*/
if (ctx->dif_type != SPDK_DIF_TYPE3) {
ref_tag = ctx->init_ref_tag + offset_blocks;
ref_tag = ctx->init_ref_tag + ctx->ref_tag_offset + offset_blocks;
} else {
ref_tag = ctx->init_ref_tag;
ref_tag = ctx->init_ref_tag + ctx->ref_tag_offset;
}
if (ctx->dif_flags & SPDK_DIF_FLAGS_GUARD_CHECK) {

View File

@ -562,7 +562,7 @@ bdevperf_generate_dif(struct bdevperf_task *task)
spdk_bdev_is_dif_head_of_md(bdev),
spdk_bdev_get_dif_type(bdev),
target->dif_check_flags,
task->offset_blocks, 0, 0, 0);
task->offset_blocks, 0, 0, 0, 0);
if (rc != 0) {
fprintf(stderr, "Initialization of DIF context failed\n");
return rc;

View File

@ -272,7 +272,7 @@ int
spdk_dif_ctx_init(struct spdk_dif_ctx *ctx, uint32_t block_size, uint32_t md_size,
bool md_interleave, bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags,
uint32_t init_ref_tag, uint16_t apptag_mask, uint16_t app_tag,
uint16_t guard_seed)
uint32_t data_offset, uint16_t guard_seed)
{
ctx->init_ref_tag = init_ref_tag;
return 0;

View File

@ -294,7 +294,7 @@ dif_sec_512_md_0_error_test(void)
int rc;
/* Metadata size is 0. */
rc = spdk_dif_ctx_init(&ctx, 512, 0, true, false, SPDK_DIF_TYPE1, 0, 0, 0, 0, 0);
rc = spdk_dif_ctx_init(&ctx, 512, 0, true, false, SPDK_DIF_TYPE1, 0, 0, 0, 0, 0, 0);
CU_ASSERT(rc != 0);
}
@ -315,7 +315,7 @@ dif_guard_seed_test(void)
dif = (struct spdk_dif *)(iov.iov_base + 512);
rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1,
SPDK_DIF_FLAGS_GUARD_CHECK, 0, 0, 0, 0);
SPDK_DIF_FLAGS_GUARD_CHECK, 0, 0, 0, 0, 0);
CU_ASSERT(rc == 0);
rc = spdk_dif_generate(&iov, 1, 1, &ctx);
@ -329,7 +329,7 @@ dif_guard_seed_test(void)
CU_ASSERT(rc == 0);
rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1,
SPDK_DIF_FLAGS_GUARD_CHECK, 0, 0, 0, GUARD_SEED);
SPDK_DIF_FLAGS_GUARD_CHECK, 0, 0, 0, 0, GUARD_SEED);
CU_ASSERT(rc == 0);
rc = spdk_dif_generate(&iov, 1, 1, &ctx);
@ -358,7 +358,7 @@ dif_generate_and_verify(struct iovec *iovs, int iovcnt,
CU_ASSERT(rc == 0);
rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, dif_type, dif_flags,
init_ref_tag, apptag_mask, app_tag, GUARD_SEED);
init_ref_tag, apptag_mask, app_tag, 0, GUARD_SEED);
CU_ASSERT(rc == 0);
rc = spdk_dif_generate(iovs, iovcnt, num_blocks, &ctx);
@ -663,7 +663,7 @@ _dif_inject_error_and_verify(struct iovec *iovs, int iovcnt,
CU_ASSERT(rc == 0);
rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc,
SPDK_DIF_TYPE1, dif_flags, 88, 0xFFFF, 0x88, GUARD_SEED);
SPDK_DIF_TYPE1, dif_flags, 88, 0xFFFF, 0x88, 0, GUARD_SEED);
CU_ASSERT(rc == 0);
rc = spdk_dif_generate(iovs, iovcnt, num_blocks, &ctx);
@ -821,7 +821,7 @@ dif_copy_gen_and_verify(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov
CU_ASSERT(rc == 0);
rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, dif_type, dif_flags,
init_ref_tag, apptag_mask, app_tag, GUARD_SEED);
init_ref_tag, apptag_mask, app_tag, 0, GUARD_SEED);
CU_ASSERT(rc == 0);
rc = spdk_dif_generate_copy(iovs, iovcnt, bounce_iov, num_blocks, &ctx);
@ -992,7 +992,7 @@ _dif_copy_inject_error_and_verify(struct iovec *iovs, int iovcnt, struct iovec *
CU_ASSERT(rc == 0);
rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, SPDK_DIF_TYPE1, dif_flags,
88, 0xFFFF, 0x88, GUARD_SEED);
88, 0xFFFF, 0x88, 0, GUARD_SEED);
SPDK_CU_ASSERT_FATAL(rc == 0);
rc = spdk_dif_generate_copy(iovs, iovcnt, bounce_iov, num_blocks, &ctx);
@ -1097,7 +1097,7 @@ dix_sec_512_md_0_error(void)
struct spdk_dif_ctx ctx;
int rc;
rc = spdk_dif_ctx_init(&ctx, 512, 0, false, false, SPDK_DIF_TYPE1, 0, 0, 0, 0, 0);
rc = spdk_dif_ctx_init(&ctx, 512, 0, false, false, SPDK_DIF_TYPE1, 0, 0, 0, 0, 0, 0);
CU_ASSERT(rc != 0);
}
@ -1114,7 +1114,7 @@ dix_generate_and_verify(struct iovec *iovs, int iovcnt, struct iovec *md_iov,
CU_ASSERT(rc == 0);
rc = spdk_dif_ctx_init(&ctx, block_size, md_size, false, dif_loc, dif_type, dif_flags,
init_ref_tag, apptag_mask, app_tag, GUARD_SEED);
init_ref_tag, apptag_mask, app_tag, 0, GUARD_SEED);
CU_ASSERT(rc == 0);
rc = spdk_dix_generate(iovs, iovcnt, md_iov, num_blocks, &ctx);
@ -1280,7 +1280,7 @@ _dix_inject_error_and_verify(struct iovec *iovs, int iovcnt, struct iovec *md_io
CU_ASSERT(rc == 0);
rc = spdk_dif_ctx_init(&ctx, block_size, md_size, false, dif_loc, SPDK_DIF_TYPE1, dif_flags,
88, 0xFFFF, 0x88, GUARD_SEED);
88, 0xFFFF, 0x88, 0, GUARD_SEED);
CU_ASSERT(rc == 0);
rc = spdk_dix_generate(iovs, iovcnt, md_iov, num_blocks, &ctx);
@ -1399,7 +1399,7 @@ set_md_interleave_iovs_test(void)
SPDK_DIF_FLAGS_REFTAG_CHECK;
rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1,
dif_check_flags, 22, 0xFFFF, 0x22, GUARD_SEED);
dif_check_flags, 22, 0xFFFF, 0x22, 0, GUARD_SEED);
CU_ASSERT(rc == 0);
/* The first data buffer:
@ -1522,7 +1522,7 @@ set_md_interleave_iovs_split_test(void)
SPDK_DIF_FLAGS_REFTAG_CHECK;
rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1,
dif_check_flags, 22, 0xFFFF, 0x22, GUARD_SEED);
dif_check_flags, 22, 0xFFFF, 0x22, 0, GUARD_SEED);
CU_ASSERT(rc == 0);
/* The first SGL data buffer:
@ -1676,7 +1676,7 @@ dif_generate_stream_test(void)
SPDK_DIF_FLAGS_REFTAG_CHECK;
rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1, dif_flags,
22, 0xFFFF, 0x22, GUARD_SEED);
22, 0xFFFF, 0x22, 0, GUARD_SEED);
CU_ASSERT(rc == 0);
rc = spdk_dif_generate_stream(&iov, 1, 0, 511, &ctx);
@ -1724,7 +1724,7 @@ update_crc32c_test(void)
SPDK_DIF_FLAGS_REFTAG_CHECK;
rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1,
dif_flags, 0, 0, 0, 0);
dif_flags, 0, 0, 0, 0, 0);
CU_ASSERT(rc == 0);
/* data[0][255:0] */