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:
parent
e48475b776
commit
05dd3c0bb2
@ -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.
|
||||
|
@ -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);
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user