diff --git a/CHANGELOG.md b/CHANGELOG.md index 67b98b9ab..bbe2009ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ ## v21.04: (Upcoming Release) + +### nvme + +Added an accelerated table pointer in spdk_nvme_poll_group +which can be used provide the accelerated functions by users with +hardware engine, such as crc32c accelerated function. + ### bdev For `bdev_ocssd_create` RPC, the optional parameter `range` was removed. diff --git a/examples/nvme/perf/perf.c b/examples/nvme/perf/perf.c index 623c4a378..20abe9b87 100644 --- a/examples/nvme/perf/perf.c +++ b/examples/nvme/perf/perf.c @@ -961,7 +961,7 @@ nvme_init_ns_worker_ctx(struct ns_worker_ctx *ns_ctx) opts.delay_cmd_submit = true; opts.create_only = true; - ns_ctx->u.nvme.group = spdk_nvme_poll_group_create(NULL); + ns_ctx->u.nvme.group = spdk_nvme_poll_group_create(NULL, NULL); if (ns_ctx->u.nvme.group == NULL) { goto poll_group_failed; } diff --git a/include/spdk/nvme.h b/include/spdk/nvme.h index 7f1fb7279..ab66365eb 100644 --- a/include/spdk/nvme.h +++ b/include/spdk/nvme.h @@ -258,6 +258,36 @@ struct spdk_nvme_ctrlr_opts { uint64_t fabrics_connect_timeout_us; }; +/** + * NVMe acceleration operation callback. + * + * \param cb_arg The user provided arg which is passed to the corresponding accelerated function call + * defined in struct spdk_nvme_accel_fn_table. + * \param status 0 if it completed successfully, or negative errno if it failed. + */ +typedef void (*spdk_nvme_accel_completion_cb)(void *cb_arg, int status); + +/** + * Function table for the NVMe acccelerator device. + * + * This table provides a set of APIs to allow user to leverage + * accelerator functions. + */ +struct spdk_nvme_accel_fn_table { + /** + * The size of spdk_nvme_accel_fun_table according to the caller of + * this library is used for ABI compatibility. The library uses this + * field to know how many fields in this structure are valid. + * And the library will populate any remaining fields with default values. + * Newly added fields should be put at the end of the struct. + */ + size_t table_size; + + /** The accelerated crc32c function. */ + void (*submit_accel_crc32c)(void *ctx, uint32_t *dst, struct iovec *iov, + uint32_t iov_cnt, uint32_t seed, spdk_nvme_accel_completion_cb cb_fn, void *cb_arg); +}; + /** * Indicate whether a ctrlr handle is associated with a Discovery controller. * @@ -2209,10 +2239,13 @@ typedef void (*spdk_nvme_disconnected_qpair_cb)(struct spdk_nvme_qpair *qpair, * Create a new poll group. * * \param ctx A user supplied context that can be retrieved later with spdk_nvme_poll_group_get_ctx + * \param table The call back table defined by users which contains the accelerated functions + * which can be used to accelerate some operations such as crc32c. * * \return Pointer to the new poll group, or NULL on error. */ -struct spdk_nvme_poll_group *spdk_nvme_poll_group_create(void *ctx); +struct spdk_nvme_poll_group *spdk_nvme_poll_group_create(void *ctx, + struct spdk_nvme_accel_fn_table *table); /** * Get a optimal poll group. diff --git a/lib/nvme/nvme_internal.h b/lib/nvme/nvme_internal.h index 82b611a39..74cf12875 100644 --- a/lib/nvme/nvme_internal.h +++ b/lib/nvme/nvme_internal.h @@ -454,6 +454,7 @@ struct spdk_nvme_qpair { struct spdk_nvme_poll_group { void *ctx; + struct spdk_nvme_accel_fn_table accel_fn_table; STAILQ_HEAD(, spdk_nvme_transport_poll_group) tgroups; }; diff --git a/lib/nvme/nvme_poll_group.c b/lib/nvme/nvme_poll_group.c index 587ed1e2d..ed015e105 100644 --- a/lib/nvme/nvme_poll_group.c +++ b/lib/nvme/nvme_poll_group.c @@ -35,7 +35,7 @@ #include "nvme_internal.h" struct spdk_nvme_poll_group * -spdk_nvme_poll_group_create(void *ctx) +spdk_nvme_poll_group_create(void *ctx, struct spdk_nvme_accel_fn_table *table) { struct spdk_nvme_poll_group *group; @@ -44,6 +44,22 @@ spdk_nvme_poll_group_create(void *ctx) return NULL; } + group->accel_fn_table.table_size = sizeof(struct spdk_nvme_accel_fn_table); + if (table && table->table_size != 0) { + group->accel_fn_table.table_size = table->table_size; +#define SET_FIELD(field) \ + if (offsetof(struct spdk_nvme_accel_fn_table, field) + sizeof(table->field) <= table->table_size) { \ + group->accel_fn_table.field = table->field; \ + } \ + + SET_FIELD(submit_accel_crc32c); + /* Do not remove this statement, you should always update this statement when you adding a new field, + * and do not forget to add the SET_FIELD statement for your added field. */ + SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_accel_fn_table) == 16, "Incorrect size"); + +#undef SET_FIELD + } + group->ctx = ctx; STAILQ_INIT(&group->tgroups); diff --git a/module/bdev/nvme/bdev_nvme.c b/module/bdev/nvme/bdev_nvme.c index daad167e9..18e025da0 100644 --- a/module/bdev/nvme/bdev_nvme.c +++ b/module/bdev/nvme/bdev_nvme.c @@ -941,7 +941,7 @@ bdev_nvme_poll_group_create_cb(void *io_device, void *ctx_buf) { struct nvme_bdev_poll_group *group = ctx_buf; - group->group = spdk_nvme_poll_group_create(group); + group->group = spdk_nvme_poll_group_create(group, NULL); if (group->group == NULL) { return -1; } diff --git a/test/unit/lib/bdev/nvme/bdev_nvme.c/bdev_nvme_ut.c b/test/unit/lib/bdev/nvme/bdev_nvme.c/bdev_nvme_ut.c index 867f707d1..95a0e780d 100644 --- a/test/unit/lib/bdev/nvme/bdev_nvme.c/bdev_nvme_ut.c +++ b/test/unit/lib/bdev/nvme/bdev_nvme.c/bdev_nvme_ut.c @@ -35,7 +35,7 @@ #include "spdk_cunit.h" #include "spdk/thread.h" #include "spdk/bdev_module.h" -#include "spdk/util.h" +#include "spdk/bdev_module.h" #include "common/lib/ut_multithread.c" @@ -189,6 +189,7 @@ struct spdk_nvme_ctrlr { struct spdk_nvme_poll_group { void *ctx; + struct spdk_nvme_accel_fn_table accel_fn_table; TAILQ_HEAD(, spdk_nvme_qpair) qpairs; }; @@ -701,7 +702,7 @@ spdk_nvme_ns_cmd_dataset_management(struct spdk_nvme_ns *ns, struct spdk_nvme_qp } struct spdk_nvme_poll_group * -spdk_nvme_poll_group_create(void *ctx) +spdk_nvme_poll_group_create(void *ctx, struct spdk_nvme_accel_fn_table *table) { struct spdk_nvme_poll_group *group; @@ -711,6 +712,9 @@ spdk_nvme_poll_group_create(void *ctx) } group->ctx = ctx; + if (table != NULL) { + group->accel_fn_table = *table; + } TAILQ_INIT(&group->qpairs); return group; diff --git a/test/unit/lib/nvme/nvme_poll_group.c/nvme_poll_group_ut.c b/test/unit/lib/nvme/nvme_poll_group.c/nvme_poll_group_ut.c index 88375006f..09321c684 100644 --- a/test/unit/lib/nvme/nvme_poll_group.c/nvme_poll_group_ut.c +++ b/test/unit/lib/nvme/nvme_poll_group.c/nvme_poll_group_ut.c @@ -205,7 +205,7 @@ test_spdk_nvme_poll_group_create(void) struct spdk_nvme_poll_group *group; /* basic case - create a poll group with no internal transport poll groups. */ - group = spdk_nvme_poll_group_create(NULL); + group = spdk_nvme_poll_group_create(NULL, NULL); SPDK_CU_ASSERT_FATAL(group != NULL); CU_ASSERT(STAILQ_EMPTY(&group->tgroups)); @@ -216,13 +216,13 @@ test_spdk_nvme_poll_group_create(void) TAILQ_INSERT_TAIL(&g_spdk_nvme_transports, &t3, link); /* advanced case - create a poll group with three internal poll groups. */ - group = spdk_nvme_poll_group_create(NULL); + group = spdk_nvme_poll_group_create(NULL, NULL); CU_ASSERT(STAILQ_EMPTY(&group->tgroups)); SPDK_CU_ASSERT_FATAL(spdk_nvme_poll_group_destroy(group) == 0); /* Failing case - failed to allocate a poll group. */ MOCK_SET(calloc, NULL); - group = spdk_nvme_poll_group_create(NULL); + group = spdk_nvme_poll_group_create(NULL, NULL); CU_ASSERT(group == NULL); MOCK_CLEAR(calloc); @@ -251,7 +251,7 @@ test_spdk_nvme_poll_group_add_remove(void) TAILQ_INSERT_TAIL(&g_spdk_nvme_transports, &t2, link); TAILQ_INSERT_TAIL(&g_spdk_nvme_transports, &t3, link); - group = spdk_nvme_poll_group_create(NULL); + group = spdk_nvme_poll_group_create(NULL, NULL); SPDK_CU_ASSERT_FATAL(group != NULL); CU_ASSERT(STAILQ_EMPTY(&group->tgroups)); @@ -379,7 +379,7 @@ test_spdk_nvme_poll_group_process_completions(void) struct spdk_nvme_transport_poll_group *tgroup, *tmp_tgroup; struct spdk_nvme_qpair qpair1_1 = {0}; - group = spdk_nvme_poll_group_create(NULL); + group = spdk_nvme_poll_group_create(NULL, NULL); SPDK_CU_ASSERT_FATAL(group != NULL); /* If we don't have any transport poll groups, we shouldn't get any completions. */ @@ -393,7 +393,7 @@ test_spdk_nvme_poll_group_process_completions(void) TAILQ_INSERT_TAIL(&g_spdk_nvme_transports, &t3, link); /* try it with three transport poll groups. */ - group = spdk_nvme_poll_group_create(NULL); + group = spdk_nvme_poll_group_create(NULL, NULL); SPDK_CU_ASSERT_FATAL(group != NULL); qpair1_1.state = NVME_QPAIR_DISCONNECTED; qpair1_1.transport = &t1; @@ -424,14 +424,14 @@ test_spdk_nvme_poll_group_destroy(void) int num_tgroups = 0; /* Simple destruction of empty poll group. */ - group = spdk_nvme_poll_group_create(NULL); + group = spdk_nvme_poll_group_create(NULL, NULL); SPDK_CU_ASSERT_FATAL(group != NULL); SPDK_CU_ASSERT_FATAL(spdk_nvme_poll_group_destroy(group) == 0); TAILQ_INSERT_TAIL(&g_spdk_nvme_transports, &t1, link); TAILQ_INSERT_TAIL(&g_spdk_nvme_transports, &t2, link); TAILQ_INSERT_TAIL(&g_spdk_nvme_transports, &t3, link); - group = spdk_nvme_poll_group_create(NULL); + group = spdk_nvme_poll_group_create(NULL, NULL); SPDK_CU_ASSERT_FATAL(group != NULL); qpair1_1.transport = &t1;