From 11c2e05fd8340bbe7041c7b7e54dfa2d2674de11 Mon Sep 17 00:00:00 2001 From: paul luse Date: Wed, 17 Jun 2020 14:10:46 -0400 Subject: [PATCH] lib/accel: add support for batching compare commands Adds support for both the accel fw and the sw implementation. Signed-off-by: paul luse Change-Id: Ib8748f272a688a074ca475a86dea14179acc020d Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/2928 Tested-by: SPDK CI Jenkins Reviewed-by: Shuhei Matsumoto Reviewed-by: Ben Walker --- include/spdk/accel_engine.h | 20 ++++++++++++ include/spdk_internal/accel_engine.h | 2 ++ lib/accel/accel_engine.c | 46 ++++++++++++++++++++++++++-- lib/accel/spdk_accel.map | 1 + 4 files changed, 67 insertions(+), 2 deletions(-) diff --git a/include/spdk/accel_engine.h b/include/spdk/accel_engine.h index 2f8076a978..30653ea807 100644 --- a/include/spdk/accel_engine.h +++ b/include/spdk/accel_engine.h @@ -226,6 +226,26 @@ int spdk_accel_submit_dualcast(struct spdk_accel_task *accel_req, struct spdk_io void *dst1, void *dst2, void *src, uint64_t nbytes, spdk_accel_completion_cb cb); +/** + * Synchronous call to prepare a compare request into a previously initialized batch + * created with spdk_accel_batch_create(). The callback will be called when the comapre + * 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 src1 First location to perform compare on. + * \param src2 Second location to perform compare on. + * \param nbytes Length in bytes to compare. + * \param cb Called when this operation completes. + * + * \return 0 on success, negative errno on failure. + */ +int spdk_accel_batch_prep_compare(struct spdk_accel_task *accel_req, struct spdk_io_channel *ch, + struct spdk_accel_batch *batch, void *src1, void *src2, + uint64_t nbytes, spdk_accel_completion_cb cb); + /** * Submit a compare request. * diff --git a/include/spdk_internal/accel_engine.h b/include/spdk_internal/accel_engine.h index eba7acf2ba..6dc0349fcd 100644 --- a/include/spdk_internal/accel_engine.h +++ b/include/spdk_internal/accel_engine.h @@ -56,6 +56,8 @@ struct spdk_accel_engine { void *dst, void *src, uint64_t nbytes, spdk_accel_completion_cb cb); int (*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); + 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_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, diff --git a/lib/accel/accel_engine.c b/lib/accel/accel_engine.c index 3fb0241488..31e8b2925b 100644 --- a/lib/accel/accel_engine.c +++ b/lib/accel/accel_engine.c @@ -202,6 +202,19 @@ spdk_accel_batch_prep_dualcast(struct spdk_accel_task *accel_req, struct spdk_io batch, dst1, dst2, src, nbytes, _accel_engine_done); } +/* Accel framework public API for batch prep_compare function */ +int +spdk_accel_batch_prep_compare(struct spdk_accel_task *accel_req, struct spdk_io_channel *ch, + struct spdk_accel_batch *batch, void *src1, void *src2, 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_compare(accel_req->offload_ctx, accel_ch->ch, + batch, src1, src2, 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, @@ -530,6 +543,29 @@ sw_accel_batch_prep_dualcast(void *cb_arg, struct spdk_io_channel *ch, return 0; } +static int +sw_accel_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) +{ + 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->src = src1; + op->src2 = src2; + op->nbytes = nbytes; + op->op_code = SW_ACCEL_OPCODE_COMPARE; + 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) @@ -537,6 +573,7 @@ sw_accel_batch_submit(void *cb_arg, struct spdk_io_channel *ch, struct spdk_acce struct sw_accel_op *op; struct sw_accel_io_channel *sw_ch = spdk_io_channel_get_ctx(ch); struct spdk_accel_task *accel_req; + int batch_status = 0, cmd_status = 0; if ((struct spdk_accel_batch *)&sw_ch->batch != batch) { SPDK_ERRLOG("Invalid batch\n"); @@ -557,19 +594,23 @@ sw_accel_batch_submit(void *cb_arg, struct spdk_io_channel *ch, struct spdk_acce memcpy(op->dst, op->src, op->nbytes); memcpy(op->dst2, op->src, op->nbytes); break; + case SW_ACCEL_OPCODE_COMPARE: + cmd_status = memcmp(op->src, op->src2, op->nbytes); + break; default: assert(false); break; } - op->cb_fn(accel_req, 0); + batch_status |= cmd_status; + op->cb_fn(accel_req, cmd_status); TAILQ_INSERT_TAIL(&sw_ch->op_pool, op, link); } /* Now complete the batch request itself. */ accel_req = (struct spdk_accel_task *)((uintptr_t)cb_arg - offsetof(struct spdk_accel_task, offload_ctx)); - cb(accel_req, 0); + cb(accel_req, batch_status); return 0; } @@ -661,6 +702,7 @@ static struct spdk_accel_engine sw_accel_engine = { .batch_create = sw_accel_batch_start, .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_submit = sw_accel_batch_submit, .compare = sw_accel_submit_compare, .fill = sw_accel_submit_fill, diff --git a/lib/accel/spdk_accel.map b/lib/accel/spdk_accel.map index 0c63e3bfd8..c6dbc37d4a 100644 --- a/lib/accel/spdk_accel.map +++ b/lib/accel/spdk_accel.map @@ -12,6 +12,7 @@ spdk_accel_batch_create; spdk_accel_batch_prep_copy; spdk_accel_batch_prep_dualcast; + spdk_accel_batch_prep_compare; spdk_accel_batch_submit; spdk_accel_submit_copy; spdk_accel_submit_dualcast;