lib/accel: add batch functionality for fill command

Also as a minor drive-by, added verify capability for fill that
wasn't there before, useful in making sure the prep function
was working and really should have been there anyway.

idxd support for prep fill will follow.

Signed-off-by: paul luse <paul.e.luse@intel.com>
Change-Id: Ib54311c1fb98abd2fb61df6603cf3c5300b71161
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/2952
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
This commit is contained in:
paul luse 2020-06-18 15:56:01 -04:00 committed by Jim Harris
parent a7dfca5b45
commit d207237fc4
5 changed files with 83 additions and 1 deletions

View File

@ -290,6 +290,12 @@ _accel_done(void *arg1)
worker->xfer_failed++;
}
break;
case ACCEL_FILL:
if (memcmp(task->dst, task->src, g_xfer_size_bytes)) {
SPDK_NOTICELOG("Data miscompare\n");
worker->xfer_failed++;
}
break;
default:
assert(false);
break;
@ -438,6 +444,11 @@ _get_task_data_bufs(struct ap_task *task)
memset(task->dst, ~DATA_PATTERN, g_xfer_size_bytes);
}
/* For fill, set the entire src buffer so we can check if verify is enabled. */
if (g_workload_selection == ACCEL_FILL) {
memset(task->src, g_fill_pattern, g_xfer_size_bytes);
}
if (g_workload_selection == ACCEL_DUALCAST) {
task->dst2 = spdk_dma_zmalloc(g_xfer_size_bytes, align, NULL);
if (task->dst2 == NULL) {
@ -471,6 +482,11 @@ _batch_prep_cmd(struct worker_thread *worker, struct ap_task *task, struct spdk_
worker->ch, batch, task->dst, task->src,
g_xfer_size_bytes, accel_done);
break;
case ACCEL_FILL:
rc = spdk_accel_batch_prep_fill(__accel_task_from_ap_task(task),
worker->ch, batch, task->dst, *(uint8_t *)task->src,
g_xfer_size_bytes, accel_done);
break;
default:
assert(false);
break;
@ -524,7 +540,8 @@ _init_thread(void *arg1)
/* 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_COMPARE ||
g_workload_selection == ACCEL_FILL)
&& ((g_capabilites & ACCEL_BATCH) == ACCEL_BATCH) &&
g_queue_depth > 1) {

View File

@ -262,6 +262,26 @@ int spdk_accel_submit_compare(struct spdk_accel_task *accel_req, struct spdk_io_
void *src1, void *src2, uint64_t nbytes,
spdk_accel_completion_cb cb);
/**
* Synchronous call to prepare a fill request into a previously initialized batch
* created with spdk_accel_batch_create(). The callback will be called when the fill
* 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 fill.
* \param fill Constant byte to fill to the destination.
* \param nbytes Length in bytes to fill.
* \param cb Called when this operation completes.
*
* \return 0 on success, negative errno on failure.
*/
int spdk_accel_batch_prep_fill(struct spdk_accel_task *accel_req, struct spdk_io_channel *ch,
struct spdk_accel_batch *batch, void *dst, uint8_t fill,
uint64_t nbytes, spdk_accel_completion_cb cb);
/**
* Submit a fill request.
*

View File

@ -58,6 +58,8 @@ struct spdk_accel_engine {
void *dst1, void *dst2, void *src, uint64_t nbytes, spdk_accel_completion_cb cb);
int (*batch_prep_compare)(void *cb_arg, struct spdk_io_channel *ch, struct spdk_accel_batch *batch,
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_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

@ -255,6 +255,21 @@ spdk_accel_batch_prep_compare(struct spdk_accel_task *accel_req, struct spdk_io_
batch, src1, src2, nbytes, _accel_engine_done);
}
/* Accel framework public API for batch prep_fill function. All engines are
* required to implement this API.
*/
int
spdk_accel_batch_prep_fill(struct spdk_accel_task *accel_req, struct spdk_io_channel *ch,
struct spdk_accel_batch *batch, void *dst, uint8_t fill, 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_fill(accel_req->offload_ctx, accel_ch->ch,
batch, dst, fill, 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,
@ -626,6 +641,29 @@ sw_accel_batch_prep_compare(void *cb_arg, struct spdk_io_channel *ch,
return 0;
}
static int
sw_accel_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)
{
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 = dst;
op->fill_pattern = fill;
op->nbytes = nbytes;
op->op_code = SW_ACCEL_OPCODE_MEMFILL;
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)
@ -657,6 +695,9 @@ sw_accel_batch_submit(void *cb_arg, struct spdk_io_channel *ch, struct spdk_acce
case SW_ACCEL_OPCODE_COMPARE:
cmd_status = memcmp(op->src, op->src2, op->nbytes);
break;
case SW_ACCEL_OPCODE_MEMFILL:
memset(op->dst, op->fill_pattern, op->nbytes);
break;
default:
assert(false);
break;
@ -759,6 +800,7 @@ static struct spdk_accel_engine sw_accel_engine = {
.batch_prep_copy = sw_accel_batch_prep_copy,
.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_submit = sw_accel_batch_submit,
.compare = sw_accel_submit_compare,
.fill = sw_accel_submit_fill,

View File

@ -13,6 +13,7 @@
spdk_accel_batch_prep_copy;
spdk_accel_batch_prep_dualcast;
spdk_accel_batch_prep_compare;
spdk_accel_batch_prep_fill;
spdk_accel_batch_submit;
spdk_accel_submit_copy;
spdk_accel_submit_dualcast;