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

Also update accel_perf to support it.

Signed-off-by: paul luse <paul.e.luse@intel.com>
Change-Id: Ida7b863de02c64239ec4cfbdc3b0235d4e0521f9
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/2954
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
paul luse 2020-06-18 17:20:26 -04:00 committed by Jim Harris
parent 396b05a3e4
commit e54f14a52b
5 changed files with 75 additions and 7 deletions

View File

@ -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);

View File

@ -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.
*

View File

@ -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,

View File

@ -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,

View File

@ -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;