Commit 759a700f authored by Shuhei Matsumoto's avatar Shuhei Matsumoto Committed by Darek Stojaczyk
Browse files

dif: Merge single and multiple iovecs cases of spdk_dif_set_md_interleave_iovs



Even if the code for single iovec case is removed, no performance
difference was observed when inserting/striping DIF for iSCSI target.

And the subsequent patches will add more complex operation and hence
simplifying the code before them will be valuable.

So this patch merges dif_set_md_interleave_iovs and
dif_set_md_interleave_iovs_split into the latter.

Signed-off-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Change-Id: I784b9e04f0983ed91c7aa66bbc7ceaed4406e3ac
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/457758


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarDarek Stojaczyk <dariusz.stojaczyk@intel.com>
parent 11bbb26e
Loading
Loading
Loading
Loading
+19 −87
Original line number Diff line number Diff line
@@ -1365,69 +1365,36 @@ spdk_dix_inject_error(struct iovec *iovs, int iovcnt, struct iovec *md_iov,
	return 0;
}

static int
dif_set_md_interleave_iovs(struct iovec *iovs, int iovcnt,
			   uint8_t *buf, uint32_t buf_len,
int
spdk_dif_set_md_interleave_iovs(struct iovec *iovs, int iovcnt,
				struct iovec *buf_iovs, int buf_iovcnt,
				uint32_t data_offset, uint32_t data_len,
				uint32_t *_mapped_len,
				const struct spdk_dif_ctx *ctx)
{
	uint32_t data_block_size, head_unalign;
	uint32_t num_blocks, offset_blocks;
	struct _dif_sgl sgl;

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

	num_blocks = data_len / data_block_size;

	if (buf_len < num_blocks * ctx->block_size) {
		SPDK_ERRLOG("Buffer overflow will occur. Buffer size is %" PRIu32 " but"
			    " necessary size is %" PRIu32 "\n",
			    buf_len, num_blocks * ctx->block_size);
		return -ERANGE;
	}

	offset_blocks = data_offset / data_block_size;
	head_unalign = data_offset % data_block_size;

	_dif_sgl_init(&sgl, iovs, iovcnt);
	buf += offset_blocks * ctx->block_size;

	while (offset_blocks < num_blocks) {
		buf += head_unalign;
	struct _dif_sgl dif_sgl;
	struct _dif_sgl buf_sgl;
	uint8_t *buf;
	uint32_t buf_len, remaining;

		if (!_dif_sgl_append(&sgl, buf, data_block_size - head_unalign)) {
			break;
	if (iovs == NULL || iovcnt == 0 || buf_iovs == NULL || buf_iovcnt == 0) {
		return -EINVAL;
	}

		buf += ctx->block_size - head_unalign;
		offset_blocks++;

		head_unalign = 0;
	}
	data_block_size = ctx->block_size - ctx->md_size;

	if (_mapped_len != NULL) {
		*_mapped_len = sgl.total_size;
	if ((data_len % data_block_size) != 0) {
		SPDK_ERRLOG("Data length must be a multiple of data block size\n");
		return -EINVAL;
	}

	return iovcnt - sgl.iovcnt;
	if (data_offset >= data_len) {
		SPDK_ERRLOG("Data offset must be smaller than data length\n");
		return -ERANGE;
	}

static int
dif_set_md_interleave_iovs_split(struct iovec *iovs, int iovcnt,
				 struct iovec *buf_iovs, int buf_iovcnt,
				 uint32_t data_offset, uint32_t data_len,
				 uint32_t *_mapped_len,
				 const struct spdk_dif_ctx *ctx)
{
	uint32_t data_block_size, head_unalign;
	uint32_t num_blocks, offset_blocks;
	struct _dif_sgl dif_sgl;
	struct _dif_sgl buf_sgl;
	uint8_t *buf;
	uint32_t buf_len, remaining;

	data_block_size = ctx->block_size - ctx->md_size;
	num_blocks = data_len / data_block_size;

	_dif_sgl_init(&dif_sgl, iovs, iovcnt);
@@ -1471,41 +1438,6 @@ end:
	return iovcnt - dif_sgl.iovcnt;
}

int
spdk_dif_set_md_interleave_iovs(struct iovec *iovs, int iovcnt,
				struct iovec *buf_iovs, int buf_iovcnt,
				uint32_t data_offset, uint32_t data_len,
				uint32_t *_mapped_len,
				const struct spdk_dif_ctx *ctx)
{
	uint32_t data_block_size;

	if (iovs == NULL || iovcnt == 0 || buf_iovs == NULL || buf_iovcnt == 0) {
		return -EINVAL;
	}

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

	if ((data_len % data_block_size) != 0) {
		SPDK_ERRLOG("Data length must be a multiple of data block size\n");
		return -EINVAL;
	}

	if (data_offset >= data_len) {
		SPDK_ERRLOG("Data offset must be smaller than data length\n");
		return -ERANGE;
	}

	if (buf_iovcnt == 1) {
		return dif_set_md_interleave_iovs(iovs, iovcnt,
						  buf_iovs[0].iov_base, buf_iovs[0].iov_len,
						  data_offset, data_len, _mapped_len, ctx);
	} else {
		return dif_set_md_interleave_iovs_split(iovs, iovcnt, buf_iovs, buf_iovcnt,
							data_offset, data_len, _mapped_len, ctx);
	}
}

static int
dif_generate_stream(uint8_t *buf, uint32_t buf_len,
		    uint32_t data_offset, uint32_t data_len,