diff --git a/include/spdk/accel_engine.h b/include/spdk/accel_engine.h index 938b57b6a1..766e42e5ca 100644 --- a/include/spdk/accel_engine.h +++ b/include/spdk/accel_engine.h @@ -135,6 +135,24 @@ uint64_t spdk_accel_get_capabilities(struct spdk_io_channel *ch); int spdk_accel_submit_copy(struct spdk_accel_task *accel_req, struct spdk_io_channel *ch, void *dst, void *src, uint64_t nbytes, spdk_accel_completion_cb cb); +/** + * Submit a dual cast copy request. + * + * \param accel_req Accel request task. + * \param ch I/O channel to submit request to the accel engine. This channel can + * be obtained by the function spdk_accel_engine_get_io_channel(). + * \param dst1 First destination to copy to (must be 4K aligned). + * \param dst2 Second destination to copy to (must be 4K aligned). + * \param src Source to copy from. + * \param nbytes Length in bytes to copy. + * \param cb Called when this copy operation completes. + * + * \return 0 on success, negative errno on failure. + */ +int spdk_accel_submit_dualcast(struct spdk_accel_task *accel_req, struct spdk_io_channel *ch, + void *dst1, void *dst2, void *src, uint64_t nbytes, + spdk_accel_completion_cb cb); + /** * Submit a compare request. * @@ -149,8 +167,8 @@ int spdk_accel_submit_copy(struct spdk_accel_task *accel_req, struct spdk_io_cha * \return 0 on success, any other value means there was a miscompare. */ int spdk_accel_submit_compare(struct spdk_accel_task *accel_req, struct spdk_io_channel *ch, - void *src1, - void *src2, uint64_t nbytes, spdk_accel_completion_cb cb); + void *src1, void *src2, uint64_t nbytes, + spdk_accel_completion_cb cb); /** * Submit a fill request. diff --git a/lib/accel/Makefile b/lib/accel/Makefile index 33026bf3bf..0d41104de7 100644 --- a/lib/accel/Makefile +++ b/lib/accel/Makefile @@ -36,6 +36,7 @@ include $(SPDK_ROOT_DIR)/mk/spdk.common.mk SO_VER := 3 SO_MINOR := 0 +SO_SUFFIX := $(SO_VER).$(SO_MINOR) LIBNAME = accel C_SRCS = accel_engine.c diff --git a/lib/accel/accel_engine.c b/lib/accel/accel_engine.c index 49e323c541..d8c30700a9 100644 --- a/lib/accel/accel_engine.c +++ b/lib/accel/accel_engine.c @@ -48,6 +48,8 @@ * later in this file. */ +#define ALIGN_4K 0x1000 + /* Largest context size for all accel modules */ static size_t g_max_accel_module_size = 0; @@ -121,6 +123,25 @@ spdk_accel_submit_copy(struct spdk_accel_task *accel_req, struct spdk_io_channel _accel_engine_done); } +/* Accel framework public API for dual cast copy function */ +int +spdk_accel_submit_dualcast(struct spdk_accel_task *accel_req, struct spdk_io_channel *ch, + void *dst1, void *dst2, void *src, uint64_t nbytes, + spdk_accel_completion_cb cb) +{ + struct spdk_accel_task *req = accel_req; + struct accel_io_channel *accel_ch = spdk_io_channel_get_ctx(ch); + + if ((uintptr_t)dst1 & (ALIGN_4K - 1) || (uintptr_t)dst2 & (ALIGN_4K - 1)) { + SPDK_ERRLOG("Dualcast requires 4K alignment on dst addresses\n"); + return -EINVAL; + } + + req->cb = cb; + return accel_ch->engine->dualcast(req->offload_ctx, accel_ch->ch, dst1, dst2, src, 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, @@ -316,7 +337,8 @@ spdk_accel_engine_config_text(FILE *fp) static uint64_t sw_accel_get_capabilities(void) { - return ACCEL_COPY | ACCEL_FILL | ACCEL_CRC32C | ACCEL_COMPARE; + return ACCEL_COPY | ACCEL_FILL | ACCEL_CRC32C | ACCEL_COMPARE | + ACCEL_DUALCAST; } static int @@ -334,6 +356,21 @@ sw_accel_submit_copy(void *cb_arg, struct spdk_io_channel *ch, void *dst, void * return 0; } +static int +sw_accel_submit_dualcast(void *cb_arg, struct spdk_io_channel *ch, void *dst1, void *dst2, + void *src, uint64_t nbytes, spdk_accel_completion_cb cb) +{ + struct spdk_accel_task *accel_req; + + memcpy(dst1, src, (size_t)nbytes); + memcpy(dst2, src, (size_t)nbytes); + + accel_req = (struct spdk_accel_task *)((uintptr_t)cb_arg - + offsetof(struct spdk_accel_task, offload_ctx)); + cb(accel_req, 0); + return 0; +} + static int sw_accel_submit_compare(void *cb_arg, struct spdk_io_channel *ch, void *src1, void *src2, uint64_t nbytes, @@ -386,6 +423,7 @@ static struct spdk_io_channel *sw_accel_get_io_channel(void); static struct spdk_accel_engine sw_accel_engine = { .get_capabilities = sw_accel_get_capabilities, .copy = sw_accel_submit_copy, + .dualcast = sw_accel_submit_dualcast, .compare = sw_accel_submit_compare, .fill = sw_accel_submit_fill, .crc32c = sw_accel_submit_crc32c, diff --git a/lib/accel/spdk_accel.map b/lib/accel/spdk_accel.map index fe3fbc4ac6..abab7a7fc9 100644 --- a/lib/accel/spdk_accel.map +++ b/lib/accel/spdk_accel.map @@ -9,6 +9,7 @@ spdk_accel_engine_get_io_channel; spdk_accel_get_capabilities; spdk_accel_submit_copy; + spdk_accel_submit_dualcast; spdk_accel_submit_compare; spdk_accel_submit_fill; spdk_accel_submit_crc32c;