lib/idxd: add support for batching the fill command

Signed-off-by: paul luse <paul.e.luse@intel.com>
Change-Id: I0996db55e78b7b74bf0a603ac0e9825a4d80d2e9
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/2953
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>
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
paul luse 2020-06-18 16:39:28 -04:00 committed by Jim Harris
parent d207237fc4
commit 396b05a3e4
4 changed files with 81 additions and 4 deletions

View File

@ -275,7 +275,27 @@ int spdk_idxd_submit_compare(struct spdk_idxd_io_channel *chan,
spdk_idxd_req_cb cb_fn, void *cb_arg);
/**
* Build and submit an idxd memory fill request.
* Synchronous call to prepare a fill request into a previously initialized batch
* created with spdk_idxd_batch_create(). The callback will be called when the fill
* 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_accel_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.
* \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_fill(struct spdk_idxd_io_channel *chan, struct idxd_batch *batch,
void *dst, uint64_t fill_pattern, uint64_t nbytes, spdk_idxd_req_cb cb_fn, void *cb_arg);
/**
* Build and submit a idxd memory fill request.
*
* This function will build the fill descriptor and then immediately submit
* by writing to the proper device portal.

View File

@ -820,8 +820,7 @@ spdk_idxd_submit_compare(struct spdk_idxd_io_channel *chan, void *src1, const vo
int
spdk_idxd_submit_fill(struct spdk_idxd_io_channel *chan, void *dst, uint64_t fill_pattern,
uint64_t nbytes,
spdk_idxd_req_cb cb_fn, void *cb_arg)
uint64_t nbytes, spdk_idxd_req_cb cb_fn, void *cb_arg)
{
struct idxd_hw_desc *desc;
@ -1005,6 +1004,45 @@ spdk_idxd_batch_prep_copy(struct spdk_idxd_io_channel *chan, struct idxd_batch *
return 0;
}
int
spdk_idxd_batch_prep_fill(struct spdk_idxd_io_channel *chan, struct idxd_batch *batch,
void *dst, uint64_t fill_pattern, 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->flags = IDXD_FLAG_COMPLETION_ADDR_VALID | IDXD_FLAG_REQUEST_COMPLETION;
desc->opcode = IDXD_OPCODE_MEMFILL;
desc->pattern = fill_pattern;
desc->dst_addr = (uintptr_t)dst;
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;
}
int
spdk_idxd_batch_prep_dualcast(struct spdk_idxd_io_channel *chan, struct idxd_batch *batch,
void *dst1, void *dst2, const void *src, uint64_t nbytes, spdk_idxd_req_cb cb_fn, void *cb_arg)
@ -1114,6 +1152,7 @@ _spdk_idxd_process_batch_events(struct spdk_idxd_io_channel *chan)
status = comp->hw.result;
}
break;
case IDXD_OPCODE_MEMFILL:
case IDXD_OPCODE_DUALCAST:
case IDXD_OPCODE_MEMMOVE:
break;

View File

@ -7,7 +7,8 @@
spdk_idxd_probe;
spdk_idxd_detach;
spdk_idxd_batch_prep_copy;
spdk_idxd_batch_prep_dualcast;
spdk_idxd_batch_prep_dualcast;
spdk_idxd_batch_prep_fill;
spdk_idxd_batch_submit;
spdk_idxd_batch_create;
spdk_idxd_batch_get_max;

View File

@ -496,6 +496,22 @@ idxd_batch_prep_copy(void *cb_arg, struct spdk_io_channel *ch, struct spdk_accel
idxd_done, idxd_task);
}
static int
idxd_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 idxd_task *idxd_task = (struct idxd_task *)cb_arg;
struct idxd_io_channel *chan = spdk_io_channel_get_ctx(ch);
uint64_t fill_pattern;
struct idxd_batch *batch = (struct idxd_batch *)_batch;
idxd_task->cb = cb;
memset(&fill_pattern, fill, sizeof(uint64_t));
return spdk_idxd_batch_prep_fill(chan->chan, batch, dst, fill_pattern, nbytes, idxd_done,
idxd_task);
}
static int
idxd_batch_prep_dualcast(void *cb_arg, struct spdk_io_channel *ch, struct spdk_accel_batch *_batch,
void *dst1, void *dst2, void *src, uint64_t nbytes, spdk_accel_completion_cb cb)
@ -516,6 +532,7 @@ static struct spdk_accel_engine idxd_accel_engine = {
.batch_get_max = idxd_batch_get_max,
.batch_create = idxd_batch_start,
.batch_prep_copy = idxd_batch_prep_copy,
.batch_prep_fill = idxd_batch_prep_fill,
.batch_prep_dualcast = idxd_batch_prep_dualcast,
.batch_submit = idxd_batch_submit,
.dualcast = idxd_submit_dualcast,