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

lib/accel: add batch prep for crc32c to accel fw and sw engine



Also update accel_perf to support it.

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


Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Community-CI: Mellanox Build Bot
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent 396b05a3
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -487,6 +487,11 @@ _batch_prep_cmd(struct worker_thread *worker, struct ap_task *task, struct spdk_
						worker->ch, batch, task->dst, *(uint8_t *)task->src,
						g_xfer_size_bytes, accel_done);
		break;
	case ACCEL_CRC32C:
		rc = spdk_accel_batch_prep_crc32c(__accel_task_from_ap_task(task),
						  worker->ch, batch, (uint32_t *)task->dst, task->src,
						  g_crc32c_seed, g_xfer_size_bytes, accel_done);
		break;
	default:
		assert(false);
		break;
@@ -537,13 +542,8 @@ _init_thread(void *arg1)
	g_num_workers++;
	pthread_mutex_unlock(&g_workers_lock);

	/* TODO: remove the workload selection checks once all are added. */
	if ((g_workload_selection == ACCEL_COPY ||
	     g_workload_selection == ACCEL_DUALCAST ||
	     g_workload_selection == ACCEL_COMPARE ||
	     g_workload_selection == ACCEL_FILL)
	    && ((g_capabilites & ACCEL_BATCH) == ACCEL_BATCH) &&
	    g_queue_depth > 1) {
	/* TODO: remove batch check once implemented for IOAT */
	if ((g_capabilites & ACCEL_BATCH) == ACCEL_BATCH && g_queue_depth > 1) {

		/* Selected engine supports batching and we have enough, so do it. */
		max_per_batch = spdk_accel_batch_get_max(worker->ch);
+21 −0
Original line number Diff line number Diff line
@@ -299,6 +299,27 @@ int spdk_accel_batch_prep_fill(struct spdk_accel_task *accel_req, struct spdk_io
int spdk_accel_submit_fill(struct spdk_accel_task *accel_req, struct spdk_io_channel *ch,
			   void *dst, uint8_t fill, uint64_t nbytes, spdk_accel_completion_cb cb);

/**
 * Synchronous call to prepare a crc32c request into a previously initialized batch
 *  created with spdk_accel_batch_create(). The callback will be called when the crc32c
 *  completes after the batch has been submitted by an asynchronous call to
 *  spdk_accel_batch_submit().
 *
 * \param accel_req Accel request task.
 * \param ch I/O channel to submit request to the accel engine.
 * \param batch Handle provided when the batch was started with spdk_accel_batch_create().
 * \param dst Destination to write the CRC-32C to.
 * \param src The source address for the data.
 * \param seed Four byte seed value.
 * \param nbytes Length in bytes.
 * \param cb Called when this operation completes.
 *
 * \return 0 on success, negative errno on failure.
 */
int spdk_accel_batch_prep_crc32c(struct spdk_accel_task *accel_req, 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);

/**
 * Submit a CRC-32C calculation request.
 *
+3 −0
Original line number Diff line number Diff line
@@ -60,6 +60,9 @@ struct spdk_accel_engine {
				  void *src1, void *src2, uint64_t nbytes, spdk_accel_completion_cb cb);
	int (*batch_prep_fill)(void *cb_arg, struct spdk_io_channel *ch, struct spdk_accel_batch *batch,
			       void *dst, uint8_t fill, uint64_t nbytes, spdk_accel_completion_cb cb);
	int (*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);
	int (*batch_submit)(void *cb_arg, struct spdk_io_channel *ch, struct spdk_accel_batch *batch,
			    spdk_accel_completion_cb cb);
	int (*compare)(void *cb_arg, struct spdk_io_channel *ch, void *src1, void *src2,
+43 −0
Original line number Diff line number Diff line
@@ -270,6 +270,21 @@ spdk_accel_batch_prep_fill(struct spdk_accel_task *accel_req, struct spdk_io_cha
			batch, dst, fill, nbytes, _accel_engine_done);
}

/* Accel framework public API for batch prep_crc32c function.  All engines are
 * required to implement this API.
 */
int
spdk_accel_batch_prep_crc32c(struct spdk_accel_task *accel_req, 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 accel_io_channel *accel_ch = spdk_io_channel_get_ctx(ch);

	accel_req->cb = cb;
	return accel_ch->engine->batch_prep_crc32c(accel_req->offload_ctx, accel_ch->ch,
			batch, dst, src, seed, nbytes, _accel_engine_done);
}

/* Accel framework public API for compare function */
int
spdk_accel_submit_compare(struct spdk_accel_task *accel_req, struct spdk_io_channel *ch,
@@ -664,6 +679,30 @@ sw_accel_batch_prep_fill(void *cb_arg, struct spdk_io_channel *ch,
	return 0;
}

static int
sw_accel_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 sw_accel_op *op;
	struct sw_accel_io_channel *sw_ch = spdk_io_channel_get_ctx(ch);

	op = _prep_op(cb_arg, sw_ch, batch, cb);
	if (op == NULL) {
		return -EINVAL;
	}

	/* Command specific. */
	op->dst = (void *)dst;
	op->src = src;
	op->seed = seed;
	op->nbytes = nbytes;
	op->op_code = SW_ACCEL_OPCODE_CRC32C;
	TAILQ_INSERT_TAIL(&sw_ch->batch, op, link);

	return 0;
}

static int
sw_accel_batch_submit(void *cb_arg, struct spdk_io_channel *ch, struct spdk_accel_batch *batch,
		      spdk_accel_completion_cb cb)
@@ -698,6 +737,9 @@ sw_accel_batch_submit(void *cb_arg, struct spdk_io_channel *ch, struct spdk_acce
		case SW_ACCEL_OPCODE_MEMFILL:
			memset(op->dst, op->fill_pattern, op->nbytes);
			break;
		case SW_ACCEL_OPCODE_CRC32C:
			*(uint32_t *)op->dst = spdk_crc32c_update(op->src, op->nbytes, ~op->seed);
			break;
		default:
			assert(false);
			break;
@@ -801,6 +843,7 @@ static struct spdk_accel_engine sw_accel_engine = {
	.batch_prep_dualcast	= sw_accel_batch_prep_dualcast,
	.batch_prep_compare	= sw_accel_batch_prep_compare,
	.batch_prep_fill	= sw_accel_batch_prep_fill,
	.batch_prep_crc32c	= sw_accel_batch_prep_crc32c,
	.batch_submit		= sw_accel_batch_submit,
	.compare		= sw_accel_submit_compare,
	.fill			= sw_accel_submit_fill,
+1 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
	spdk_accel_batch_prep_dualcast;
	spdk_accel_batch_prep_compare;
	spdk_accel_batch_prep_fill;
	spdk_accel_batch_prep_crc32c;
	spdk_accel_batch_submit;
	spdk_accel_submit_copy;
	spdk_accel_submit_dualcast;