dif: enhance copy API to support block-aligned bounce_iov

When iovs are copied from bounce or to bounce, the bounce is usually
alloced from data_buf_pool for better performance, and is multi iovs
instead of a single buffer. Therefore, block-aligned bounce are
supported.

Signed-off-by: Chunsong Feng <fengchunsong@huawei.com>
Change-Id: If56b21d9e46c73d4c956c227bec33ddd0ab9745b
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/11860
Community-CI: Mellanox Build Bot
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Shuhei Matsumoto <smatsumoto@nvidia.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
This commit is contained in:
Chunsong Feng 2022-03-09 08:32:50 +00:00 committed by Tomasz Zawadzki
parent e48475b776
commit 05dd3c0bb2
4 changed files with 56 additions and 20 deletions

View File

@ -2,6 +2,12 @@
## v22.05: (Upcoming Release)
### util
A new parameter `bounce_iovcnt` was added to `spdk_dif_generate_copy` and `spdk_dif_verify_copy`.
The `bounce_iovcnt` is used to specify the number of bounce_iov to support multiple block-aligned
fragment copies.
### bdev
Removed deprecated spdk_bdev_module_finish_done(). Use spdk_bdev_module_fini_done() instead.

View File

@ -220,29 +220,33 @@ int spdk_dif_update_crc32c(struct iovec *iovs, int iovcnt, uint32_t num_blocks,
*
* \param iovs iovec array describing the LBA payload.
* \param iovcnt Number of elements in the iovec array.
* \param bounce_iov A contiguous buffer forming extended LBA payload.
* \param bounce_iovs A contiguous buffer forming extended LBA payload.
* \param bounce_iovcnt Number of elements in the bounce_iovs array.
* \param num_blocks Number of blocks of the LBA payload.
* \param ctx DIF context.
*
* \return 0 on success and negated errno otherwise.
*/
int spdk_dif_generate_copy(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov,
uint32_t num_blocks, const struct spdk_dif_ctx *ctx);
int spdk_dif_generate_copy(struct iovec *iovs, int iovcnt, struct iovec *bounce_iovs,
int bounce_iovcnt, uint32_t num_blocks,
const struct spdk_dif_ctx *ctx);
/**
* Verify DIF and copy data for extended LBA payload.
*
* \param iovs iovec array describing the LBA payload.
* \param iovcnt Number of elements in the iovec array.
* \param bounce_iov A contiguous buffer forming extended LBA payload.
* \param bounce_iovs A contiguous buffer forming extended LBA payload.
* \param bounce_iovcnt Number of elements in the bounce_iovs array.
* \param num_blocks Number of blocks of the LBA payload.
* \param ctx DIF context.
* \param err_blk Error information of the block in which DIF error is found.
*
* \return 0 on success and negated errno otherwise.
*/
int spdk_dif_verify_copy(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov,
uint32_t num_blocks, const struct spdk_dif_ctx *ctx,
int spdk_dif_verify_copy(struct iovec *iovs, int iovcnt, struct iovec *bounce_iovs,
int bounce_iovcnt, uint32_t num_blocks,
const struct spdk_dif_ctx *ctx,
struct spdk_dif_error *err_blk);
/**

View File

@ -143,6 +143,22 @@ _dif_sgl_is_bytes_multiple(struct _dif_sgl *s, uint32_t bytes)
return true;
}
static bool
_dif_sgl_is_valid_block_aligned(struct _dif_sgl *s, uint32_t num_blocks, uint32_t block_size)
{
uint32_t count = 0;
int i;
for (i = 0; i < s->iovcnt; i++) {
if (s->iov[i].iov_len % block_size) {
return false;
}
count += s->iov[i].iov_len / block_size;
}
return count >= num_blocks;
}
/* This function must be used before starting iteration. */
static bool
_dif_sgl_is_valid(struct _dif_sgl *s, uint32_t bytes)
@ -880,23 +896,28 @@ dif_generate_copy_split(struct _dif_sgl *src_sgl, struct _dif_sgl *dst_sgl,
}
int
spdk_dif_generate_copy(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov,
uint32_t num_blocks, const struct spdk_dif_ctx *ctx)
spdk_dif_generate_copy(struct iovec *iovs, int iovcnt, struct iovec *bounce_iovs,
int bounce_iovcnt, uint32_t num_blocks,
const struct spdk_dif_ctx *ctx)
{
struct _dif_sgl src_sgl, dst_sgl;
uint32_t data_block_size;
_dif_sgl_init(&src_sgl, iovs, iovcnt);
_dif_sgl_init(&dst_sgl, bounce_iov, 1);
_dif_sgl_init(&dst_sgl, bounce_iovs, bounce_iovcnt);
data_block_size = ctx->block_size - ctx->md_size;
if (!_dif_sgl_is_valid(&src_sgl, data_block_size * num_blocks) ||
!_dif_sgl_is_valid(&dst_sgl, ctx->block_size * num_blocks)) {
if (!_dif_sgl_is_valid(&src_sgl, data_block_size * num_blocks)) {
SPDK_ERRLOG("Size of iovec arrays are not valid.\n");
return -EINVAL;
}
if (!_dif_sgl_is_valid_block_aligned(&dst_sgl, num_blocks, ctx->block_size)) {
SPDK_ERRLOG("Size of bounce_iovs arrays are not valid or misaligned with block_size.\n");
return -EINVAL;
}
if (_dif_is_disabled(ctx->dif_type)) {
return 0;
}
@ -1013,24 +1034,29 @@ dif_verify_copy_split(struct _dif_sgl *src_sgl, struct _dif_sgl *dst_sgl,
}
int
spdk_dif_verify_copy(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov,
uint32_t num_blocks, const struct spdk_dif_ctx *ctx,
spdk_dif_verify_copy(struct iovec *iovs, int iovcnt, struct iovec *bounce_iovs,
int bounce_iovcnt, uint32_t num_blocks,
const struct spdk_dif_ctx *ctx,
struct spdk_dif_error *err_blk)
{
struct _dif_sgl src_sgl, dst_sgl;
uint32_t data_block_size;
_dif_sgl_init(&src_sgl, bounce_iov, 1);
_dif_sgl_init(&src_sgl, bounce_iovs, bounce_iovcnt);
_dif_sgl_init(&dst_sgl, iovs, iovcnt);
data_block_size = ctx->block_size - ctx->md_size;
if (!_dif_sgl_is_valid(&dst_sgl, data_block_size * num_blocks) ||
!_dif_sgl_is_valid(&src_sgl, ctx->block_size * num_blocks)) {
if (!_dif_sgl_is_valid(&dst_sgl, data_block_size * num_blocks)) {
SPDK_ERRLOG("Size of iovec arrays are not valid\n");
return -EINVAL;
}
if (!_dif_sgl_is_valid_block_aligned(&src_sgl, num_blocks, ctx->block_size)) {
SPDK_ERRLOG("Size of bounce_iovs arrays are not valid or misaligned with block_size.\n");
return -EINVAL;
}
if (_dif_is_disabled(ctx->dif_type)) {
return 0;
}

View File

@ -824,10 +824,10 @@ dif_copy_gen_and_verify(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov
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);
rc = spdk_dif_generate_copy(iovs, iovcnt, bounce_iov, 1, num_blocks, &ctx);
CU_ASSERT(rc == 0);
rc = spdk_dif_verify_copy(iovs, iovcnt, bounce_iov, num_blocks, &ctx, NULL);
rc = spdk_dif_verify_copy(iovs, iovcnt, bounce_iov, 1, num_blocks, &ctx, NULL);
CU_ASSERT(rc == 0);
rc = ut_data_pattern_verify(iovs, iovcnt, block_size - md_size, 0, num_blocks);
@ -995,13 +995,13 @@ _dif_copy_inject_error_and_verify(struct iovec *iovs, int iovcnt, struct iovec *
88, 0xFFFF, 0x88, 0, GUARD_SEED);
SPDK_CU_ASSERT_FATAL(rc == 0);
rc = spdk_dif_generate_copy(iovs, iovcnt, bounce_iov, num_blocks, &ctx);
rc = spdk_dif_generate_copy(iovs, iovcnt, bounce_iov, 1, num_blocks, &ctx);
CU_ASSERT(rc == 0);
rc = spdk_dif_inject_error(bounce_iov, 1, num_blocks, &ctx, inject_flags, &inject_offset);
CU_ASSERT(rc == 0);
rc = spdk_dif_verify_copy(iovs, iovcnt, bounce_iov, num_blocks, &ctx, &err_blk);
rc = spdk_dif_verify_copy(iovs, iovcnt, bounce_iov, 1, num_blocks, &ctx, &err_blk);
CU_ASSERT(rc != 0);
if (inject_flags == SPDK_DIF_DATA_ERROR) {
CU_ASSERT(SPDK_DIF_GUARD_ERROR == err_blk.err_type);