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)
### 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.

View File

@ -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;
}

View File

@ -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.

View File

@ -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;
};

View File

@ -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);

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;
group->group = spdk_nvme_poll_group_create(group);
group->group = spdk_nvme_poll_group_create(group, NULL);
if (group->group == NULL) {
return -1;
}

View File

@ -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;

View File

@ -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;