diff --git a/CHANGELOG.md b/CHANGELOG.md index 580631cbc..7cb45b1a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ The NVMe-oF target no longer supports connecting scheduling configuration and instead always uses what was previously called "transport" scheduling. +`spdk_nvmf_tgt_accept` no longer takes a function pointer as an argument. New connections +are automatically assigned to poll groups by the underlying transport. + ### nvme Add `opts_size` in `spdk_nvme_ctrlr_opts` structure in order to solve the compatiblity issue diff --git a/examples/nvmf/nvmf/nvmf.c b/examples/nvmf/nvmf/nvmf.c index d44bdcfb4..22e271fb3 100644 --- a/examples/nvmf/nvmf/nvmf.c +++ b/examples/nvmf/nvmf/nvmf.c @@ -517,98 +517,12 @@ nvmf_tgt_stop_subsystems(struct nvmf_target *nvmf_tgt) } } -struct nvmf_target_pg_ctx { - struct spdk_nvmf_qpair *qpair; - struct nvmf_target_poll_group *pg; -}; - -static void -nvmf_tgt_pg_add_qpair(void *_ctx) -{ - struct nvmf_target_pg_ctx *ctx = _ctx; - struct spdk_nvmf_qpair *qpair = ctx->qpair; - struct nvmf_target_poll_group *pg = ctx->pg; - - free(_ctx); - - if (spdk_nvmf_poll_group_add(pg->group, qpair) != 0) { - fprintf(stderr, "unable to add the qpair to a poll group.\n"); - spdk_nvmf_qpair_disconnect(qpair, NULL, NULL); - } -} - -static struct nvmf_target_poll_group * -nvmf_tgt_get_next_pg(struct nvmf_target *nvmf_tgt) -{ - struct nvmf_target_poll_group *pg; - - pg = g_next_pg; - g_next_pg = TAILQ_NEXT(pg, link); - if (g_next_pg == NULL) { - g_next_pg = TAILQ_FIRST(&g_poll_groups); - } - - return pg; -} - -static struct nvmf_target_poll_group * -nvmf_get_optimal_pg(struct nvmf_target *nvmf_tgt, struct spdk_nvmf_qpair *qpair) -{ - struct nvmf_target_poll_group *pg, *_pg = NULL; - struct spdk_nvmf_poll_group *group = spdk_nvmf_get_optimal_poll_group(qpair); - - if (group == NULL) { - _pg = nvmf_tgt_get_next_pg(nvmf_tgt); - goto end; - } - - TAILQ_FOREACH(pg, &g_poll_groups, link) { - if (pg->group == group) { - _pg = pg; - break; - } - } - -end: - assert(_pg != NULL); - return _pg; -} - -static void -new_qpair(struct spdk_nvmf_qpair *qpair, void *cb_arg) -{ - struct nvmf_target_poll_group *pg; - struct nvmf_target_pg_ctx *ctx; - struct nvmf_target *nvmf_tgt = &g_nvmf_tgt; - - /* In SPDK we support three methods to get poll group: RoundRobin, Host and Transport. - * In this example we only support the "Transport" which gets the optimal poll group. - */ - pg = nvmf_get_optimal_pg(nvmf_tgt, qpair); - if (!pg) { - spdk_nvmf_qpair_disconnect(qpair, NULL, NULL); - return; - } - - ctx = calloc(1, sizeof(*ctx)); - if (!ctx) { - fprintf(stderr, "failed to allocate poll group context.\n"); - spdk_nvmf_qpair_disconnect(qpair, NULL, NULL); - return; - } - - ctx->qpair = qpair; - ctx->pg = pg; - - spdk_thread_send_msg(pg->thread, nvmf_tgt_pg_add_qpair, ctx); -} - static int nvmf_tgt_acceptor_poll(void *arg) { struct nvmf_target *nvmf_tgt = arg; - spdk_nvmf_tgt_accept(nvmf_tgt->tgt, new_qpair, NULL); + spdk_nvmf_tgt_accept(nvmf_tgt->tgt); return -1; } diff --git a/include/spdk/nvmf.h b/include/spdk/nvmf.h index 7d5a41392..303fa4c40 100644 --- a/include/spdk/nvmf.h +++ b/include/spdk/nvmf.h @@ -114,14 +114,6 @@ struct spdk_nvmf_transport_poll_group_stat { }; }; -/** - * Function to be called for each newly discovered qpair. - * - * \param qpair The newly discovered qpair. - * \param cb_arg A context argument passed to this function. - */ -typedef void (*new_qpair_fn)(struct spdk_nvmf_qpair *qpair, void *cb_arg); - /** * Function to be called once the listener is associated with a subsystem. * @@ -233,15 +225,9 @@ int spdk_nvmf_tgt_stop_listen(struct spdk_nvmf_tgt *tgt, /** * Poll the target for incoming connections. * - * The new_qpair_fn cb_fn will be called for each newly discovered - * qpair. The user is expected to add that qpair to a poll group - * to establish the connection. - * * \param tgt The target associated with the listen address. - * \param cb_fn Called for each newly discovered qpair. - * \param cb_arg A context argument passed to cb_fn. */ -uint32_t spdk_nvmf_tgt_accept(struct spdk_nvmf_tgt *tgt, new_qpair_fn cb_fn, void *cb_arg); +uint32_t spdk_nvmf_tgt_accept(struct spdk_nvmf_tgt *tgt); /** * Create a poll group. diff --git a/include/spdk/nvmf_transport.h b/include/spdk/nvmf_transport.h index 68abc6b88..0f44b1952 100644 --- a/include/spdk/nvmf_transport.h +++ b/include/spdk/nvmf_transport.h @@ -192,6 +192,14 @@ struct spdk_nvmf_transport { TAILQ_ENTRY(spdk_nvmf_transport) link; }; +/** + * Function to be called for each newly discovered qpair. + * + * \param qpair The newly discovered qpair. + * \param cb_arg A context argument passed to this function. + */ +typedef void (*new_qpair_fn)(struct spdk_nvmf_qpair *qpair, void *cb_arg); + struct spdk_nvmf_transport_ops { /** * Transport name diff --git a/lib/nvmf/Makefile b/lib/nvmf/Makefile index e613a9a03..e23c403d8 100644 --- a/lib/nvmf/Makefile +++ b/lib/nvmf/Makefile @@ -34,7 +34,7 @@ SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..) include $(SPDK_ROOT_DIR)/mk/spdk.common.mk -SO_VER := 4 +SO_VER := 5 SO_MINOR := 0 C_SRCS = ctrlr.c ctrlr_discovery.c ctrlr_bdev.c \ diff --git a/lib/nvmf/nvmf.c b/lib/nvmf/nvmf.c index f31f8efc3..257c7a335 100644 --- a/lib/nvmf/nvmf.c +++ b/lib/nvmf/nvmf.c @@ -720,14 +720,70 @@ spdk_nvmf_tgt_get_transport(struct spdk_nvmf_tgt *tgt, const char *transport_nam return NULL; } +struct nvmf_new_qpair_ctx { + struct spdk_nvmf_qpair *qpair; + struct spdk_nvmf_poll_group *group; +}; + +static void +_nvmf_poll_group_add(void *_ctx) +{ + struct nvmf_new_qpair_ctx *ctx = _ctx; + struct spdk_nvmf_qpair *qpair = ctx->qpair; + struct spdk_nvmf_poll_group *group = ctx->group; + + free(_ctx); + + if (spdk_nvmf_poll_group_add(group, qpair) != 0) { + SPDK_ERRLOG("Unable to add the qpair to a poll group.\n"); + spdk_nvmf_qpair_disconnect(qpair, NULL, NULL); + } +} + +static void +_nvmf_new_qpair(struct spdk_nvmf_qpair *qpair, void *cb_arg) +{ + struct spdk_nvmf_poll_group *group; + struct spdk_nvmf_tgt *tgt; + struct nvmf_new_qpair_ctx *ctx; + + tgt = qpair->transport->tgt; + + group = spdk_nvmf_get_optimal_poll_group(qpair); + if (group == NULL) { + if (tgt->next_poll_group == NULL) { + tgt->next_poll_group = TAILQ_FIRST(&tgt->poll_groups); + if (tgt->next_poll_group == NULL) { + SPDK_ERRLOG("No poll groups exist.\n"); + spdk_nvmf_qpair_disconnect(qpair, NULL, NULL); + return; + } + } + group = tgt->next_poll_group; + tgt->next_poll_group = TAILQ_NEXT(group, link); + } + + ctx = calloc(1, sizeof(*ctx)); + if (!ctx) { + SPDK_ERRLOG("Unable to send message to poll group.\n"); + spdk_nvmf_qpair_disconnect(qpair, NULL, NULL); + return; + } + + ctx->qpair = qpair; + ctx->group = group; + + spdk_thread_send_msg(group->thread, _nvmf_poll_group_add, ctx); +} + uint32_t -spdk_nvmf_tgt_accept(struct spdk_nvmf_tgt *tgt, new_qpair_fn cb_fn, void *cb_arg) +spdk_nvmf_tgt_accept(struct spdk_nvmf_tgt *tgt) { struct spdk_nvmf_transport *transport, *tmp; uint32_t count = 0; TAILQ_FOREACH_SAFE(transport, &tgt->transports, link, tmp) { - count += nvmf_transport_accept(transport, cb_fn, cb_arg); + count += nvmf_transport_accept(transport, _nvmf_new_qpair, NULL); } return count; diff --git a/lib/nvmf/nvmf_internal.h b/lib/nvmf/nvmf_internal.h index cf2495372..3b3941ed2 100644 --- a/lib/nvmf/nvmf_internal.h +++ b/lib/nvmf/nvmf_internal.h @@ -74,6 +74,9 @@ struct spdk_nvmf_tgt { TAILQ_HEAD(, spdk_nvmf_transport) transports; TAILQ_HEAD(, spdk_nvmf_poll_group) poll_groups; + /* Used for round-robin assignment of connections to poll groups */ + struct spdk_nvmf_poll_group *next_poll_group; + spdk_nvmf_tgt_destroy_done_fn *destroy_cb_fn; void *destroy_cb_arg; diff --git a/module/event/subsystems/nvmf/nvmf_tgt.c b/module/event/subsystems/nvmf/nvmf_tgt.c index 20cc98083..22354cff0 100644 --- a/module/event/subsystems/nvmf/nvmf_tgt.c +++ b/module/event/subsystems/nvmf/nvmf_tgt.c @@ -69,9 +69,6 @@ static enum nvmf_tgt_state g_tgt_state; static struct spdk_thread *g_tgt_init_thread = NULL; static struct spdk_thread *g_tgt_fini_thread = NULL; -/* Round-Robin assignment of connections to poll groups */ -static struct nvmf_tgt_poll_group *g_next_poll_group = NULL; - static TAILQ_HEAD(, nvmf_tgt_poll_group) g_poll_groups = TAILQ_HEAD_INITIALIZER(g_poll_groups); static size_t g_num_poll_groups = 0; @@ -106,95 +103,13 @@ nvmf_subsystem_fini(void) nvmf_shutdown_cb(NULL); } -static struct nvmf_tgt_poll_group * -nvmf_tgt_get_pg(struct spdk_nvmf_qpair *qpair) -{ - struct nvmf_tgt_poll_group *pg; - struct spdk_nvmf_poll_group *group; - - group = spdk_nvmf_get_optimal_poll_group(qpair); - - if (group != NULL) { - /* Look up the nvmf_tgt_poll_group that matches this spdk_nvmf_poll_group */ - TAILQ_FOREACH(pg, &g_poll_groups, link) { - if (pg->group == group) { - return pg; - } - } - - return NULL; - } - - if (g_next_poll_group == NULL) { - g_next_poll_group = TAILQ_FIRST(&g_poll_groups); - if (g_next_poll_group == NULL) { - return NULL; - } - } - pg = g_next_poll_group; - g_next_poll_group = TAILQ_NEXT(pg, link); - - return pg; -} - -struct nvmf_tgt_pg_ctx { - struct spdk_nvmf_qpair *qpair; - struct nvmf_tgt_poll_group *pg; -}; - -static void -nvmf_tgt_poll_group_add(void *_ctx) -{ - struct nvmf_tgt_pg_ctx *ctx = _ctx; - struct spdk_nvmf_qpair *qpair = ctx->qpair; - struct nvmf_tgt_poll_group *pg = ctx->pg; - - free(_ctx); - - if (spdk_nvmf_poll_group_add(pg->group, qpair) != 0) { - SPDK_ERRLOG("Unable to add the qpair to a poll group.\n"); - spdk_nvmf_qpair_disconnect(qpair, NULL, NULL); - } -} - -static void -new_qpair(struct spdk_nvmf_qpair *qpair, void *cb_arg) -{ - struct nvmf_tgt_pg_ctx *ctx; - struct nvmf_tgt_poll_group *pg; - - if (g_tgt_state != NVMF_TGT_RUNNING) { - spdk_nvmf_qpair_disconnect(qpair, NULL, NULL); - return; - } - - pg = nvmf_tgt_get_pg(qpair); - if (pg == NULL) { - SPDK_ERRLOG("No poll groups exist.\n"); - spdk_nvmf_qpair_disconnect(qpair, NULL, NULL); - return; - } - - ctx = calloc(1, sizeof(*ctx)); - if (!ctx) { - SPDK_ERRLOG("Unable to send message to poll group.\n"); - spdk_nvmf_qpair_disconnect(qpair, NULL, NULL); - return; - } - - ctx->qpair = qpair; - ctx->pg = pg; - - spdk_thread_send_msg(pg->thread, nvmf_tgt_poll_group_add, ctx); -} - static int acceptor_poll(void *arg) { struct spdk_nvmf_tgt *tgt = arg; uint32_t count; - count = spdk_nvmf_tgt_accept(tgt, new_qpair, NULL); + count = spdk_nvmf_tgt_accept(tgt); return count; } @@ -251,10 +166,6 @@ nvmf_tgt_create_poll_group_done(void *ctx) TAILQ_INSERT_TAIL(&g_poll_groups, pg, link); - if (g_next_poll_group == NULL) { - g_next_poll_group = pg; - } - assert(g_num_poll_groups < spdk_env_get_core_count()); if (++g_num_poll_groups == spdk_env_get_core_count()) {