diff --git a/CHANGELOG.md b/CHANGELOG.md index cefff0018..49ef003ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,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. + ### bdev Change `spdk_bdev_read_blocks_with_md` arg offset definiton from int64_t to uint64_t. diff --git a/include/spdk/accel_engine.h b/include/spdk/accel_engine.h index 62d55cc56..051e2aadf 100644 --- a/include/spdk/accel_engine.h +++ b/include/spdk/accel_engine.h @@ -337,6 +337,28 @@ int spdk_accel_batch_prep_crc32cv(struct spdk_io_channel *ch, struct spdk_accel_ uint32_t *dst, struct iovec *iovs, uint32_t iovcnt, uint32_t seed, spdk_accel_completion_cb cb_fn, void *cb_arg); +/** + * Synchronous call to prepare a copy + crc32c request into a previously initialized batch + * created with spdk_accel_batch_create(). The callback will be called when the operation + * completes after the batch has been submitted by an asynchronous call to + * spdk_accel_batch_submit(). + * + * \param ch I/O channel associated with this call. + * \param batch Handle provided when the batch was started with spdk_accel_batch_create(). + * \param dst Destination to write the data to. + * \param src The source address for the data. + * \param crc_dst Destination to write the CRC-32C to. + * \param seed Four byte seed value. + * \param nbytes Length in bytes. + * \param cb_fn Called when this operation completes. + * \param cb_arg Callback argument. + * + * \return 0 on success, negative errno on failure. + */ +int spdk_accel_batch_prep_copy_crc32c(struct spdk_io_channel *ch, struct spdk_accel_batch *batch, + void *dst, void *src, uint32_t *crc_dst, uint32_t seed, uint64_t nbytes, + spdk_accel_completion_cb cb_fn, void *cb_arg); + /** * Submit a CRC-32C calculation request. * diff --git a/lib/accel/accel_engine.c b/lib/accel/accel_engine.c index 4c9593546..906ff4b17 100644 --- a/lib/accel/accel_engine.c +++ b/lib/accel/accel_engine.c @@ -661,6 +661,36 @@ spdk_accel_batch_prep_crc32cv(struct spdk_io_channel *ch, struct spdk_accel_batc return 0; } +int +spdk_accel_batch_prep_copy_crc32c(struct spdk_io_channel *ch, struct spdk_accel_batch *batch, + void *dst, void *src, uint32_t *crc_dst, uint32_t seed, uint64_t nbytes, + spdk_accel_completion_cb cb_fn, void *cb_arg) +{ + struct spdk_accel_task *accel_task; + struct accel_io_channel *accel_ch = spdk_io_channel_get_ctx(ch); + + accel_task = _get_task(accel_ch, batch, cb_fn, cb_arg); + if (accel_task == NULL) { + return -ENOMEM; + } + + accel_task->dst = dst; + accel_task->src = src; + accel_task->crc_dst = crc_dst; + accel_task->v.iovcnt = 0; + accel_task->seed = seed; + accel_task->nbytes = nbytes; + accel_task->op_code = ACCEL_OPCODE_COPY_CRC32C; + + if (_is_supported(accel_ch->engine, ACCEL_COPY_CRC32C)) { + TAILQ_INSERT_TAIL(&batch->hw_tasks, accel_task, link); + } else { + TAILQ_INSERT_TAIL(&batch->sw_tasks, accel_task, link); + } + + return 0; +} + /* Accel framework public API for batch_create function. */ struct spdk_accel_batch * spdk_accel_batch_create(struct spdk_io_channel *ch) @@ -748,6 +778,11 @@ spdk_accel_batch_submit(struct spdk_io_channel *ch, struct spdk_accel_batch *bat } spdk_accel_task_complete(accel_task, 0); break; + case ACCEL_OPCODE_COPY_CRC32C: + _sw_accel_copy(accel_task->dst, accel_task->src, accel_task->nbytes); + _sw_accel_crc32c(accel_task->crc_dst, accel_task->src, accel_task->seed, accel_task->nbytes); + spdk_accel_task_complete(accel_task, 0); + break; case ACCEL_OPCODE_DUALCAST: _sw_accel_dualcast(accel_task->dst, accel_task->dst2, accel_task->src, accel_task->nbytes); diff --git a/lib/accel/spdk_accel.map b/lib/accel/spdk_accel.map index 9e21f1be9..35699f7fa 100644 --- a/lib/accel/spdk_accel.map +++ b/lib/accel/spdk_accel.map @@ -15,6 +15,7 @@ spdk_accel_batch_prep_fill; spdk_accel_batch_prep_crc32c; spdk_accel_batch_prep_crc32cv; + spdk_accel_batch_prep_copy_crc32c; spdk_accel_batch_submit; spdk_accel_batch_cancel; spdk_accel_submit_copy;