Commit 80da7496 authored by paul luse's avatar paul luse Committed by Jim Harris
Browse files

lib/idxd: add support for batching crc32c requests



Signed-off-by: default avatarpaul luse <paul.e.luse@intel.com>
Change-Id: I38e8b26272e86e84e579262496b367375976638d
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/2955


Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Community-CI: Mellanox Build Bot
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent e54f14a5
Loading
Loading
Loading
Loading
+24 −2
Original line number Diff line number Diff line
@@ -281,7 +281,7 @@ int spdk_idxd_submit_compare(struct spdk_idxd_io_channel *chan,
 *  spdk_idxd_batch_submit().
 *
 * \param chan IDXD channel to submit request.
 * \param batch Handle provided when the batch was started with spdk_accel_batch_create().
 * \param batch Handle provided when the batch was started with spdk_idxd_batch_create().
 * \param dst Destination virtual address.
 * \param fill_pattern Repeating eight-byte pattern to use for memory fill.
 * \param nbytes Number of bytes to fill.
@@ -315,7 +315,29 @@ int spdk_idxd_submit_fill(struct spdk_idxd_io_channel *chan,
			  spdk_idxd_req_cb cb_fn, void *cb_arg);

/**
 * Build and submit an idxd memory CRC32-C request.
 * Synchronous call to prepare a crc32c request into a previously initialized batch
 *  created with spdk_idxd_batch_create(). The callback will be called when the crc32c
 *  completes after the batch has been submitted by an asynchronous call to
 *  spdk_idxd_batch_submit().
 *
 * \param chan IDXD channel to submit request.
 * \param batch Handle provided when the batch was started with spdk_idxd_batch_create().
 * \param dst Resulting calculation.
 * \param src Source virtual address.
 * \param seed Four byte CRC-32C seed value.
 * \param nbytes Number of bytes to calculate on.
 * \param cb_fn Callback function which will be called when the request is complete.
 * \param cb_arg Opaque value which will be passed back as the arg parameter in
 * the completion callback.
 *
 * \return 0 on success, negative errno on failure.
 */
int spdk_idxd_batch_prep_crc32c(struct spdk_idxd_io_channel *chan, struct idxd_batch *batch,
				uint32_t *dst, void *src, uint32_t seed, uint64_t nbytes,
				spdk_idxd_req_cb cb_fn, void *cb_arg);

/**
 * Build and submit a memory CRC32-C request.
 *
 * This function will build the CRC-32C descriptor and then immediately submit
 * by writing to the proper device portal.
+41 −0
Original line number Diff line number Diff line
@@ -1087,6 +1087,47 @@ spdk_idxd_batch_prep_dualcast(struct spdk_idxd_io_channel *chan, struct idxd_bat
	return 0;
}

int
spdk_idxd_batch_prep_crc32c(struct spdk_idxd_io_channel *chan, struct idxd_batch *batch,
			    uint32_t *dst, void *src, uint32_t seed, uint64_t nbytes,
			    spdk_idxd_req_cb cb_fn, void *cb_arg)
{
	struct idxd_hw_desc *desc;
	struct idxd_comp *comp;

	if (_does_batch_exist(batch, chan) == false) {
		SPDK_ERRLOG("Attempt to add to a batch that doesn't exist\n.");
		return -EINVAL;
	}

	if ((batch->cur_index - batch->start_index) == DESC_PER_BATCH) {
		SPDK_ERRLOG("Attempt to add to a batch that is already full\n.");
		return -ENOMEM;
	}

	desc = &chan->ring_ctrl.user_desc[batch->cur_index];
	comp = &chan->ring_ctrl.user_completions[batch->cur_index];
	SPDK_DEBUGLOG(SPDK_LOG_IDXD, "Prep batch %p index %u\n", batch, batch->cur_index);

	batch->cur_index++;
	assert(batch->cur_index > batch->start_index);

	desc->opcode = IDXD_OPCODE_CRC32C_GEN;
	desc->dst_addr = (uintptr_t)dst;
	desc->src_addr = (uintptr_t)src;
	desc->flags = IDXD_FLAG_COMPLETION_ADDR_VALID | IDXD_FLAG_REQUEST_COMPLETION;
	desc->flags &= IDXD_CLEAR_CRC_FLAGS;
	desc->crc32c.seed = seed;
	desc->xfer_size = nbytes;

	desc->completion_addr = (uintptr_t)&comp->hw;
	comp->cb_arg = cb_arg;
	comp->cb_fn = cb_fn;
	comp->batch = batch;

	return 0;
}

static void
_dump_error_reg(struct spdk_idxd_io_channel *chan)
{
+1 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
	spdk_idxd_batch_prep_copy;
	spdk_idxd_batch_prep_dualcast;
	spdk_idxd_batch_prep_fill;
	spdk_idxd_batch_prep_crc32c;
	spdk_idxd_batch_submit;
	spdk_idxd_batch_create;
	spdk_idxd_batch_get_max;
+16 −0
Original line number Diff line number Diff line
@@ -526,6 +526,21 @@ idxd_batch_prep_dualcast(void *cb_arg, struct spdk_io_channel *ch, struct spdk_a
					     idxd_task);
}

static int
idxd_batch_prep_crc32c(void *cb_arg, struct spdk_io_channel *ch, struct spdk_accel_batch *_batch,
		       uint32_t *dst, void *src, uint32_t seed, uint64_t nbytes,
		       spdk_accel_completion_cb cb)
{
	struct idxd_task *idxd_task = (struct idxd_task *)cb_arg;
	struct idxd_io_channel *chan = spdk_io_channel_get_ctx(ch);
	struct idxd_batch *batch = (struct idxd_batch *)_batch;

	idxd_task->cb = cb;

	return spdk_idxd_batch_prep_crc32c(chan->chan, batch, dst, src, seed, nbytes, idxd_done,
					   idxd_task);
}

static struct spdk_accel_engine idxd_accel_engine = {
	.get_capabilities	= idxd_get_capabilities,
	.copy			= idxd_submit_copy,
@@ -534,6 +549,7 @@ static struct spdk_accel_engine idxd_accel_engine = {
	.batch_prep_copy	= idxd_batch_prep_copy,
	.batch_prep_fill	= idxd_batch_prep_fill,
	.batch_prep_dualcast	= idxd_batch_prep_dualcast,
	.batch_prep_crc32c	= idxd_batch_prep_crc32c,
	.batch_submit		= idxd_batch_submit,
	.dualcast		= idxd_submit_dualcast,
	.compare		= idxd_submit_compare,