Commit 4b88d742 authored by Shuhei Matsumoto's avatar Shuhei Matsumoto Committed by Konrad Sztyber
Browse files

dif: Do copy data + insert/strip metadata if DIF is disabled



Previously, spdk_dif_generate/verify_copy() did nothing and returned
0 if DIF was disabled.

However, this was wrong.

spdk_dif_generate_copy() should copy data and insert metadata field.
spdk_dif_verify_copy() should copy data and strip metadata field.

Add such change and verify it by adding unit test cases.

Signed-off-by: default avatarShuhei Matsumoto <smatsumoto@nvidia.com>
Change-Id: I8408e360376a607864bb7f0a187abb73bb7b6e0d
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/23684


Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@nvidia.com>
Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Community-CI: Mellanox Build Bot
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent c07b6033
Loading
Loading
Loading
Loading
+74 −0
Original line number Diff line number Diff line
@@ -1230,6 +1230,42 @@ dif_generate_copy_split(struct _dif_sgl *src_sgl, struct _dif_sgl *dst_sgl,
	}
}

static void
_dif_disable_insert_copy(struct _dif_sgl *src_sgl, struct _dif_sgl *dst_sgl,
			 const struct spdk_dif_ctx *ctx)
{
	uint32_t offset = 0, src_len, dst_len, buf_len, data_block_size;
	uint8_t *src, *dst;

	data_block_size = ctx->block_size - ctx->md_size;

	while (offset < data_block_size) {
		_dif_sgl_get_buf(src_sgl, &src, &src_len);
		_dif_sgl_get_buf(dst_sgl, &dst, &dst_len);
		buf_len = spdk_min(src_len, dst_len);
		buf_len = spdk_min(buf_len, data_block_size - offset);

		memcpy(dst, src, buf_len);

		_dif_sgl_advance(src_sgl, buf_len);
		_dif_sgl_advance(dst_sgl, buf_len);
		offset += buf_len;
	}

	_dif_sgl_advance(dst_sgl, ctx->md_size);
}

static void
dif_disable_insert_copy(struct _dif_sgl *src_sgl, struct _dif_sgl *dst_sgl,
			uint32_t num_blocks, const struct spdk_dif_ctx *ctx)
{
	uint32_t offset_blocks;

	for (offset_blocks = 0; offset_blocks < num_blocks; offset_blocks++) {
		_dif_disable_insert_copy(src_sgl, dst_sgl, ctx);
	}
}

int
spdk_dif_generate_copy(struct iovec *iovs, int iovcnt, struct iovec *bounce_iovs,
		       int bounce_iovcnt, uint32_t num_blocks,
@@ -1250,6 +1286,7 @@ spdk_dif_generate_copy(struct iovec *iovs, int iovcnt, struct iovec *bounce_iovs
	}

	if (_dif_is_disabled(ctx->dif_type)) {
		dif_disable_insert_copy(&src_sgl, &dst_sgl, num_blocks, ctx);
		return 0;
	}

@@ -1360,6 +1397,42 @@ dif_verify_copy_split(struct _dif_sgl *src_sgl, struct _dif_sgl *dst_sgl,
	return 0;
}

static void
_dif_disable_strip_copy(struct _dif_sgl *src_sgl, struct _dif_sgl *dst_sgl,
			const struct spdk_dif_ctx *ctx)
{
	uint32_t offset = 0, src_len, dst_len, buf_len, data_block_size;
	uint8_t *src, *dst;

	data_block_size = ctx->block_size - ctx->md_size;

	while (offset < data_block_size) {
		_dif_sgl_get_buf(src_sgl, &src, &src_len);
		_dif_sgl_get_buf(dst_sgl, &dst, &dst_len);
		buf_len = spdk_min(src_len, dst_len);
		buf_len = spdk_min(buf_len, data_block_size - offset);

		memcpy(dst, src, buf_len);

		_dif_sgl_advance(src_sgl, buf_len);
		_dif_sgl_advance(dst_sgl, buf_len);
		offset += buf_len;
	}

	_dif_sgl_advance(src_sgl, ctx->md_size);
}

static void
dif_disable_strip_copy(struct _dif_sgl *src_sgl, struct _dif_sgl *dst_sgl,
		       uint32_t num_blocks, const struct spdk_dif_ctx *ctx)
{
	uint32_t offset_blocks;

	for (offset_blocks = 0; offset_blocks < num_blocks; offset_blocks++) {
		_dif_disable_strip_copy(src_sgl, dst_sgl, ctx);
	}
}

int
spdk_dif_verify_copy(struct iovec *iovs, int iovcnt, struct iovec *bounce_iovs,
		     int bounce_iovcnt, uint32_t num_blocks,
@@ -1381,6 +1454,7 @@ spdk_dif_verify_copy(struct iovec *iovs, int iovcnt, struct iovec *bounce_iovs,
	}

	if (_dif_is_disabled(ctx->dif_type)) {
		dif_disable_strip_copy(&src_sgl, &dst_sgl, num_blocks, ctx);
		return 0;
	}

+86 −0
Original line number Diff line number Diff line
@@ -1623,6 +1623,23 @@ dif_copy_sec_512_md_8_prchk_0_single_iov(void)
	_iov_free_buf(&bounce_iov);
}

static void
dif_copy_sec_512_md_8_dif_disable_single_iov(void)
{
	struct iovec iov, bounce_iov;

	_iov_alloc_buf(&iov, 512 * 4);
	_iov_alloc_buf(&bounce_iov, (512 + 8) * 4);

	dif_copy_gen_and_verify(&iov, 1, &bounce_iov, 1, 512 + 8, 8, 4,
				false, SPDK_DIF_DISABLE, 0, 0, 0, 0, SPDK_DIF_PI_FORMAT_16);
	dif_copy_gen_and_verify(&iov, 1, &bounce_iov, 1, 512 + 8, 8, 4,
				true, SPDK_DIF_DISABLE, 0, 0, 0, 0, SPDK_DIF_PI_FORMAT_16);

	_iov_free_buf(&iov);
	_iov_free_buf(&bounce_iov);
}

static void
_dif_copy_sec_4096_md_128_prchk_0_single_iov_test(
	enum spdk_dif_pi_format dif_pi_format)
@@ -1964,6 +1981,73 @@ dif_copy_sec_512_md_8_prchk_7_multi_bounce_iovs_complex_splits(void)
	}
}

static void
dif_copy_sec_512_md_8_dif_disable_multi_bounce_iovs_complex_splits(void)
{
	struct iovec iovs[6], bounce_iovs[7];
	int i;

	/*
	 * src_data is made of 4 blocks and its block size is 512.
	 * dst_data is made of 4 blocks and its block size is 520.
	 *
	 * The first dimension of src_data[][] and dst_data[][] represents the
	 * number of blocks, and the second dimension represents the bytes range.
	 *
	 * Test the case these data is split with arbitrary boundary.
	 */

	/* src_data[0][255:0] */
	_iov_alloc_buf(&iovs[0], 256);

	/* src_data[0][511:256], src_data[1][255:0] */
	_iov_alloc_buf(&iovs[1], 256 + 256);

	/* src_data[1][382:256] */
	_iov_alloc_buf(&iovs[2], 128);

	/* src_data[1][383] */
	_iov_alloc_buf(&iovs[3], 1);

	/* src_data[1][510:384] */
	_iov_alloc_buf(&iovs[4], 126);

	/* src_data[1][511], src_data[2][511:0], src_data[3][511:0] */
	_iov_alloc_buf(&iovs[5], 1 + 512 * 2);

	/* dst_data[0][516:0] */
	_iov_alloc_buf(&bounce_iovs[0], 517);

	/* dst_data[0][519:517], dst_data[1][260:0] */
	_iov_alloc_buf(&bounce_iovs[1], 3 + 261);

	/* dst_data[1][399:261] */
	_iov_alloc_buf(&bounce_iovs[2], 139);

	/* dst_data[1][511:400] */
	_iov_alloc_buf(&bounce_iovs[3], 112);

	/* dst_data[1][515:512] */
	_iov_alloc_buf(&bounce_iovs[4], 4);

	/* dst_data[1][519:516], dst_data[2][11:0] */
	_iov_alloc_buf(&bounce_iovs[5], 21);

	/* dst_data[1][519:12], dst_data[2][519:0], dst_data[3][519:0] */
	_iov_alloc_buf(&bounce_iovs[6], 507 + 520 + 520);

	dif_copy_gen_and_verify(iovs, 6, bounce_iovs, 7, 512 + 8, 8, 4,
				true, SPDK_DIF_DISABLE, 0, 0, 0, 0, SPDK_DIF_PI_FORMAT_16);

	for (i = 0; i < 6; i++) {
		_iov_free_buf(&iovs[i]);
	}

	for (i = 0; i < 7; i++) {
		_iov_free_buf(&bounce_iovs[i]);
	}
}

static void
dif_copy_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_test(void)
{
@@ -4373,6 +4457,7 @@ main(int argc, char **argv)
	CU_ADD_TEST(suite, dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_reftag_pi_16_test);
	CU_ADD_TEST(suite, dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_reftag_test);
	CU_ADD_TEST(suite, dif_copy_sec_512_md_8_prchk_0_single_iov);
	CU_ADD_TEST(suite, dif_copy_sec_512_md_8_dif_disable_single_iov);
	CU_ADD_TEST(suite, dif_copy_sec_4096_md_128_prchk_0_single_iov_test);
	CU_ADD_TEST(suite, dif_copy_sec_512_md_8_prchk_0_1_2_4_multi_iovs);
	CU_ADD_TEST(suite, dif_copy_sec_4096_md_128_prchk_0_1_2_4_multi_iovs_test);
@@ -4382,6 +4467,7 @@ main(int argc, char **argv)
	CU_ADD_TEST(suite, dif_copy_sec_4096_md_128_prchk_7_multi_iovs_split_data_test);
	CU_ADD_TEST(suite, dif_copy_sec_512_md_8_prchk_7_multi_iovs_complex_splits);
	CU_ADD_TEST(suite, dif_copy_sec_512_md_8_prchk_7_multi_bounce_iovs_complex_splits);
	CU_ADD_TEST(suite, dif_copy_sec_512_md_8_dif_disable_multi_bounce_iovs_complex_splits);
	CU_ADD_TEST(suite, dif_copy_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_test);
	CU_ADD_TEST(suite, dif_copy_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test);
	CU_ADD_TEST(suite, dif_copy_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_test);