lib/accel: add support for crc32 with copy using source IOVs

Support in accel_perf is coming up in a later patch.

Signed-off-by: paul luse <paul.e.luse@intel.com>
Change-Id: I63a1d3b9b1a3254fdca78e27c473b9b3468c93c8
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/8202
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Community-CI: Mellanox Build Bot
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Ziye Yang <ziye.yang@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
This commit is contained in:
paul luse 2021-06-07 16:00:15 -04:00 committed by Jim Harris
parent b4f302e525
commit 71f0600c5b
6 changed files with 95 additions and 5 deletions

View File

@ -8,6 +8,8 @@ Added API `spdk_accel_submit_copy_crc32c` to perform a CRC32C while copying data
Added API `spdk_accel_batch_prep_copy_crc32c` to batch CRC32C + copy commands.
Added API `spdk_accel_submit_copy_crc32cv` to submit chained CRC32C + copy commands.
### bdev
Change `spdk_bdev_read_blocks_with_md` arg offset definiton from int64_t to uint64_t.

View File

@ -415,6 +415,26 @@ int spdk_accel_submit_copy_crc32c(struct spdk_io_channel *ch, void *dst, void *s
uint32_t *crc_dst, uint32_t seed, uint64_t nbytes,
spdk_accel_completion_cb cb_fn, void *cb_arg);
/**
* Submit a chained copy + CRC-32C calculation request.
*
* This operation will calculate the 4 byte CRC32-C for the given data.
*
* \param ch I/O channel associated with this call.
* \param dst Destination to write the data to.
* \param src_iovs The io vector array which stores the src data and len.
* \param iovcnt The size of the io vectors.
* \param crc_dst Destination to write the CRC-32C to.
* \param seed Four byte seed value.
* \param cb_fn Called when this CRC-32C operation completes.
* \param cb_arg Callback argument.
*
* \return 0 on success, negative errno on failure.
*/
int spdk_accel_submit_copy_crc32cv(struct spdk_io_channel *ch, void *dst, struct iovec *src_iovs,
uint32_t iovcnt, uint32_t *crc_dst, uint32_t seed, spdk_accel_completion_cb cb_fn, void *cb_arg);
struct spdk_json_write_ctx;
/**

View File

@ -84,7 +84,7 @@ struct spdk_accel_task {
struct {
spdk_accel_completion_cb cb_fn;
void *cb_arg;
} chained;
} chained;
union {
struct {
struct iovec *iovs; /* iovs passed by the caller */

View File

@ -338,9 +338,18 @@ crc32cv_done(void *cb_arg, int status)
assert(accel_task->chained.cb_arg != NULL);
if (spdk_likely(!status)) {
status = spdk_accel_submit_crc32cv(ch, accel_task->dst, ++accel_task->v.iovs,
accel_task->v.iovcnt - 1, ~(*((uint32_t *)accel_task->dst)),
accel_task->chained.cb_fn, accel_task->chained.cb_arg);
if (accel_task->op_code == ACCEL_OPCODE_COPY_CRC32C) {
accel_task->dst = (char *)accel_task->dst + accel_task->nbytes;
status = spdk_accel_submit_copy_crc32cv(ch, accel_task->dst, ++accel_task->v.iovs,
accel_task->v.iovcnt - 1, accel_task->crc_dst,
~(*((uint32_t *)accel_task->crc_dst)),
accel_task->chained.cb_fn, accel_task->chained.cb_arg);
} else {
status = spdk_accel_submit_crc32cv(ch, accel_task->dst, ++accel_task->v.iovs,
accel_task->v.iovcnt - 1, ~(*((uint32_t *)accel_task->dst)),
accel_task->chained.cb_fn, accel_task->chained.cb_arg);
}
if (spdk_likely(!status)) {
return;
}
@ -433,6 +442,63 @@ spdk_accel_submit_copy_crc32c(struct spdk_io_channel *ch, void *dst, void *src,
}
}
/* Accel framework public API for chained copy + CRC-32C function */
int
spdk_accel_submit_copy_crc32cv(struct spdk_io_channel *ch, void *dst, struct iovec *src_iovs,
uint32_t iov_cnt, uint32_t *crc_dst, uint32_t seed,
spdk_accel_completion_cb cb_fn, void *cb_arg)
{
struct accel_io_channel *accel_ch;
struct spdk_accel_task *accel_task;
if (src_iovs == NULL) {
SPDK_ERRLOG("iov should not be NULL");
return -EINVAL;
}
if (!iov_cnt) {
SPDK_ERRLOG("iovcnt should not be zero value\n");
return -EINVAL;
}
if (iov_cnt == 1) {
return spdk_accel_submit_copy_crc32c(ch, dst, src_iovs[0].iov_base, crc_dst, seed,
src_iovs[0].iov_len, cb_fn, cb_arg);
}
accel_ch = spdk_io_channel_get_ctx(ch);
accel_task = _get_task(accel_ch, NULL, cb_fn, cb_arg);
if (accel_task == NULL) {
SPDK_ERRLOG("no memory\n");
assert(0);
return -ENOMEM;
}
accel_task->v.iovs = src_iovs;
accel_task->v.iovcnt = iov_cnt;
accel_task->dst = (void *)dst;
accel_task->crc_dst = crc_dst;
accel_task->seed = seed;
accel_task->op_code = ACCEL_OPCODE_COPY_CRC32C;
if (_is_supported(accel_ch->engine, ACCEL_COPY_CRC32C)) {
accel_task->cb_fn = crc32cv_done;
accel_task->cb_arg = accel_task;
accel_task->chained.cb_fn = cb_fn;
accel_task->chained.cb_arg = cb_arg;
accel_task->nbytes = src_iovs[0].iov_len;
return accel_ch->engine->submit_tasks(accel_ch->engine_ch, accel_task);
} else {
_sw_accel_copy(dst, src_iovs[0].iov_base, src_iovs[0].iov_len);
_sw_accel_crc32cv(crc_dst, src_iovs, iov_cnt, seed);
spdk_accel_task_complete(accel_task, 0);
return 0;
}
}
/* Accel framework public API for getting max operations for a batch. */
uint32_t
spdk_accel_batch_get_max(struct spdk_io_channel *ch)

View File

@ -25,6 +25,7 @@
spdk_accel_submit_crc32c;
spdk_accel_submit_crc32cv;
spdk_accel_submit_copy_crc32c;
spdk_accel_submit_copy_crc32cv;
spdk_accel_write_config_json;
# functions needed by modules

View File

@ -168,7 +168,8 @@ _process_single_task(struct spdk_io_channel *ch, struct spdk_accel_task *task)
task);
break;
case ACCEL_OPCODE_COPY_CRC32C:
rc = spdk_idxd_submit_copy_crc32c(chan->chan, task->dst, task->src, task->crc_dst, task->seed,
src = (task->v.iovcnt == 0) ? task->src : task->v.iovs[0].iov_base;
rc = spdk_idxd_submit_copy_crc32c(chan->chan, task->dst, src, task->crc_dst, task->seed,
task->nbytes, idxd_done, task);
break;
default: