Commit 05dd3c0b authored by Chunsong Feng's avatar Chunsong Feng Committed by Tomasz Zawadzki
Browse files

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: default avatarChunsong 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: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <smatsumoto@nvidia.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@mellanox.com>
parent e48475b7
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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.
+10 −6
Original line number Diff line number Diff line
@@ -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);

/**
+36 −10
Original line number Diff line number Diff line
@@ -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;
	}
+4 −4
Original line number Diff line number Diff line
@@ -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);