Commit ae27b86b authored by Krzysztof Sprzaczkowski's avatar Krzysztof Sprzaczkowski Committed by Tomasz Zawadzki
Browse files

lib/accel: DIF generate-copy accel SW implementation



Extend the Accel SW module with DIF Generate-copy operation support.

The DIF Generate-copy operation copies memory from the Source
Address to the Destination Address, while computing the Data Integrity
Field (DIF) on the source data and inserting the DIF into the output
data.

Change-Id: I0a0b94d55f7517742f3f8b7a3da4f81614f6e144
Signed-off-by: default avatarKrzysztof Sprzaczkowski <krzysztof.sprzaczkowski@intel.com>
Signed-off-by: default avatarSlawomir Ptak <slawomir.ptak@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/19853


Reviewed-by: default avatarShuhei Matsumoto <smatsumoto@nvidia.com>
Reviewed-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@nvidia.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent d65b6aad
Loading
Loading
Loading
Loading
+41 −13
Original line number Diff line number Diff line
@@ -46,7 +46,8 @@ enum spdk_accel_opcode {
	SPDK_ACCEL_OPC_DECRYPT			= 9,
	SPDK_ACCEL_OPC_XOR			= 10,
	SPDK_ACCEL_OPC_DIF_VERIFY		= 11,
	SPDK_ACCEL_OPC_LAST		= 12,
	SPDK_ACCEL_OPC_DIF_GENERATE_COPY	= 12,
	SPDK_ACCEL_OPC_LAST			= 13,
};

enum spdk_accel_cipher {
@@ -414,6 +415,33 @@ int spdk_accel_submit_dif_verify(struct spdk_io_channel *ch,
				 const struct spdk_dif_ctx *ctx, struct spdk_dif_error *err,
				 spdk_accel_completion_cb cb_fn, void *cb_arg);

/**
 * Submit a Data Integrity Field (DIF) copy and generate request.
 *
 * This operation copies memory from the source to the destination address,
 * while computing the DIF on the source data and inserting the DIF into
 * the output data.
 *
 * \param ch I/O channel associated with this call.
 * \param dst_iovs The destination io vector array. The total allocated memory size needs
 *		  to be at least: num_blocks * block_size (provided to spdk_dif_ctx_init())
 * \param dst_iovcnt The size of the destination io vectors array.
 * \param src_iovs The source io vector array. The total allocated memory size needs
 *		  to be at least: num_blocks * block_size_no_md
 * \param src_iovcnt The size of the source io vectors array.
 * \param num_blocks Number of data blocks to process.
 * \param ctx DIF context. Contains the DIF configuration values, including the reference
 *            Application Tag value and initial value of the Reference Tag to insert
 * \param cb_fn Called when this operation completes.
 * \param cb_arg Callback argument.
 *
 * \return 0 on success, negative errno on failure.
 */
int spdk_accel_submit_dif_generate_copy(struct spdk_io_channel *ch, struct iovec *dst_iovs,
					size_t dst_iovcnt, struct iovec *src_iovs, size_t src_iovcnt,
					uint32_t num_blocks, const struct spdk_dif_ctx *ctx,
					spdk_accel_completion_cb cb_fn, void *cb_arg);

/** Object grouping multiple accel operations to be executed at the same point in time */
struct spdk_accel_sequence;

+30 −1
Original line number Diff line number Diff line
@@ -77,7 +77,7 @@ static struct spdk_spinlock g_stats_lock;

static const char *g_opcode_strings[SPDK_ACCEL_OPC_LAST] = {
	"copy", "fill", "dualcast", "compare", "crc32c", "copy_crc32c",
	"compress", "decompress", "encrypt", "decrypt", "xor", "dif_verify"
	"compress", "decompress", "encrypt", "decrypt", "xor", "dif_verify", "dif_generate_copy"
};

enum accel_sequence_state {
@@ -862,6 +862,35 @@ spdk_accel_submit_dif_verify(struct spdk_io_channel *ch,
	return accel_submit_task(accel_ch, accel_task);
}

int
spdk_accel_submit_dif_generate_copy(struct spdk_io_channel *ch, struct iovec *dst_iovs,
				    size_t dst_iovcnt, struct iovec *src_iovs, size_t src_iovcnt,
				    uint32_t num_blocks, const struct spdk_dif_ctx *ctx,
				    spdk_accel_completion_cb cb_fn, void *cb_arg)
{
	struct accel_io_channel *accel_ch = spdk_io_channel_get_ctx(ch);
	struct spdk_accel_task *accel_task;

	accel_task = _get_task(accel_ch, cb_fn, cb_arg);
	if (accel_task == NULL) {
		return -ENOMEM;
	}

	accel_task->s.iovs = src_iovs;
	accel_task->s.iovcnt = src_iovcnt;
	accel_task->d.iovs = dst_iovs;
	accel_task->d.iovcnt = dst_iovcnt;
	accel_task->dif.ctx = ctx;
	accel_task->dif.num_blocks = num_blocks;
	accel_task->nbytes = num_blocks * ctx->block_size;
	accel_task->op_code = SPDK_ACCEL_OPC_DIF_GENERATE_COPY;
	accel_task->src_domain = NULL;
	accel_task->dst_domain = NULL;
	accel_task->step_cb_fn = NULL;

	return accel_submit_task(accel_ch, accel_task);
}

static inline struct accel_buffer *
accel_get_buf(struct accel_io_channel *ch, uint64_t len)
{
+15 −0
Original line number Diff line number Diff line
@@ -79,6 +79,7 @@ sw_accel_supports_opcode(enum spdk_accel_opcode opc)
	case SPDK_ACCEL_OPC_DECRYPT:
	case SPDK_ACCEL_OPC_XOR:
	case SPDK_ACCEL_OPC_DIF_VERIFY:
	case SPDK_ACCEL_OPC_DIF_GENERATE_COPY:
		return true;
	default:
		return false;
@@ -453,6 +454,17 @@ _sw_accel_dif_verify(struct sw_accel_io_channel *sw_ch, struct spdk_accel_task *
			       accel_task->dif.err);
}

static int
_sw_accel_dif_generate_copy(struct sw_accel_io_channel *sw_ch, struct spdk_accel_task *accel_task)
{
	return spdk_dif_generate_copy(accel_task->s.iovs,
				      accel_task->s.iovcnt,
				      accel_task->d.iovs,
				      accel_task->d.iovcnt,
				      accel_task->dif.num_blocks,
				      accel_task->dif.ctx);
}

static int
sw_accel_submit_tasks(struct spdk_io_channel *ch, struct spdk_accel_task *accel_task)
{
@@ -506,6 +518,9 @@ sw_accel_submit_tasks(struct spdk_io_channel *ch, struct spdk_accel_task *accel_
		case SPDK_ACCEL_OPC_DIF_VERIFY:
			rc = _sw_accel_dif_verify(sw_ch, accel_task);
			break;
		case SPDK_ACCEL_OPC_DIF_GENERATE_COPY:
			rc = _sw_accel_dif_generate_copy(sw_ch, accel_task);
			break;
		default:
			assert(false);
			break;
+1 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
	spdk_accel_submit_decrypt;
	spdk_accel_submit_xor;
	spdk_accel_submit_dif_verify;
	spdk_accel_submit_dif_generate_copy;
	spdk_accel_get_opc_module_name;
	spdk_accel_assign_opc;
	spdk_accel_write_config_json;