nvme: Add a new parameter in spdk_nvme_poll_group_create

Purpose: To setup an accelerated function callback
for created spdk_nvme_poll_group. In this patch,
we just create the interface. The real usage of this
call back will be provided in the other patch.

Signed-off-by: Ziye Yang <ziye.yang@intel.com>
Change-Id: I0d936aa4eba4dbfcc0137942156b9f2919eb5b78
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/6758
Community-CI: Broadcom CI
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
This commit is contained in:
Ziye Yang 2021-03-08 23:04:46 +08:00 committed by Tomasz Zawadzki
parent 8f5e4bfe2e
commit 6153b4aa8f
8 changed files with 75 additions and 14 deletions

View File

@ -2,6 +2,13 @@
## v21.04: (Upcoming Release) ## 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 ### bdev
For `bdev_ocssd_create` RPC, the optional parameter `range` was removed. For `bdev_ocssd_create` RPC, the optional parameter `range` was removed.

View File

@ -961,7 +961,7 @@ nvme_init_ns_worker_ctx(struct ns_worker_ctx *ns_ctx)
opts.delay_cmd_submit = true; opts.delay_cmd_submit = true;
opts.create_only = 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) { if (ns_ctx->u.nvme.group == NULL) {
goto poll_group_failed; goto poll_group_failed;
} }

View File

@ -258,6 +258,36 @@ struct spdk_nvme_ctrlr_opts {
uint64_t fabrics_connect_timeout_us; 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. * 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. * Create a new poll group.
* *
* \param ctx A user supplied context that can be retrieved later with spdk_nvme_poll_group_get_ctx * \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. * \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. * Get a optimal poll group.

View File

@ -454,6 +454,7 @@ struct spdk_nvme_qpair {
struct spdk_nvme_poll_group { struct spdk_nvme_poll_group {
void *ctx; void *ctx;
struct spdk_nvme_accel_fn_table accel_fn_table;
STAILQ_HEAD(, spdk_nvme_transport_poll_group) tgroups; STAILQ_HEAD(, spdk_nvme_transport_poll_group) tgroups;
}; };

View File

@ -35,7 +35,7 @@
#include "nvme_internal.h" #include "nvme_internal.h"
struct spdk_nvme_poll_group * 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; struct spdk_nvme_poll_group *group;
@ -44,6 +44,22 @@ spdk_nvme_poll_group_create(void *ctx)
return NULL; 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; group->ctx = ctx;
STAILQ_INIT(&group->tgroups); STAILQ_INIT(&group->tgroups);

View File

@ -941,7 +941,7 @@ bdev_nvme_poll_group_create_cb(void *io_device, void *ctx_buf)
{ {
struct nvme_bdev_poll_group *group = 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) { if (group->group == NULL) {
return -1; return -1;
} }

View File

@ -35,7 +35,7 @@
#include "spdk_cunit.h" #include "spdk_cunit.h"
#include "spdk/thread.h" #include "spdk/thread.h"
#include "spdk/bdev_module.h" #include "spdk/bdev_module.h"
#include "spdk/util.h" #include "spdk/bdev_module.h"
#include "common/lib/ut_multithread.c" #include "common/lib/ut_multithread.c"
@ -189,6 +189,7 @@ struct spdk_nvme_ctrlr {
struct spdk_nvme_poll_group { struct spdk_nvme_poll_group {
void *ctx; void *ctx;
struct spdk_nvme_accel_fn_table accel_fn_table;
TAILQ_HEAD(, spdk_nvme_qpair) qpairs; 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 * 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; struct spdk_nvme_poll_group *group;
@ -711,6 +712,9 @@ spdk_nvme_poll_group_create(void *ctx)
} }
group->ctx = ctx; group->ctx = ctx;
if (table != NULL) {
group->accel_fn_table = *table;
}
TAILQ_INIT(&group->qpairs); TAILQ_INIT(&group->qpairs);
return group; return group;

View File

@ -205,7 +205,7 @@ test_spdk_nvme_poll_group_create(void)
struct spdk_nvme_poll_group *group; struct spdk_nvme_poll_group *group;
/* basic case - create a poll group with no internal transport poll groups. */ /* 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); SPDK_CU_ASSERT_FATAL(group != NULL);
CU_ASSERT(STAILQ_EMPTY(&group->tgroups)); 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); TAILQ_INSERT_TAIL(&g_spdk_nvme_transports, &t3, link);
/* advanced case - create a poll group with three internal poll groups. */ /* 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)); CU_ASSERT(STAILQ_EMPTY(&group->tgroups));
SPDK_CU_ASSERT_FATAL(spdk_nvme_poll_group_destroy(group) == 0); SPDK_CU_ASSERT_FATAL(spdk_nvme_poll_group_destroy(group) == 0);
/* Failing case - failed to allocate a poll group. */ /* Failing case - failed to allocate a poll group. */
MOCK_SET(calloc, NULL); MOCK_SET(calloc, NULL);
group = spdk_nvme_poll_group_create(NULL); group = spdk_nvme_poll_group_create(NULL, NULL);
CU_ASSERT(group == NULL); CU_ASSERT(group == NULL);
MOCK_CLEAR(calloc); 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, &t2, link);
TAILQ_INSERT_TAIL(&g_spdk_nvme_transports, &t3, 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); SPDK_CU_ASSERT_FATAL(group != NULL);
CU_ASSERT(STAILQ_EMPTY(&group->tgroups)); 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_transport_poll_group *tgroup, *tmp_tgroup;
struct spdk_nvme_qpair qpair1_1 = {0}; 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); SPDK_CU_ASSERT_FATAL(group != NULL);
/* If we don't have any transport poll groups, we shouldn't get any completions. */ /* 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); TAILQ_INSERT_TAIL(&g_spdk_nvme_transports, &t3, link);
/* try it with three transport poll groups. */ /* 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); SPDK_CU_ASSERT_FATAL(group != NULL);
qpair1_1.state = NVME_QPAIR_DISCONNECTED; qpair1_1.state = NVME_QPAIR_DISCONNECTED;
qpair1_1.transport = &t1; qpair1_1.transport = &t1;
@ -424,14 +424,14 @@ test_spdk_nvme_poll_group_destroy(void)
int num_tgroups = 0; int num_tgroups = 0;
/* Simple destruction of empty poll group. */ /* 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(group != NULL);
SPDK_CU_ASSERT_FATAL(spdk_nvme_poll_group_destroy(group) == 0); 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, &t1, link);
TAILQ_INSERT_TAIL(&g_spdk_nvme_transports, &t2, link); TAILQ_INSERT_TAIL(&g_spdk_nvme_transports, &t2, link);
TAILQ_INSERT_TAIL(&g_spdk_nvme_transports, &t3, 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); SPDK_CU_ASSERT_FATAL(group != NULL);
qpair1_1.transport = &t1; qpair1_1.transport = &t1;