From 1c53379bdfd33bbd1cc952bf426097e68bc81a50 Mon Sep 17 00:00:00 2001 From: Jin Yu Date: Thu, 21 Nov 2019 20:18:00 +0800 Subject: [PATCH] nvmf_example: initlize the bdev layer Change-Id: I92f6c03f944ef51b2a325b64055861d8376e5134 Signed-off-by: Jin Yu Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/475414 Community-CI: Broadcom SPDK FC-NVMe CI Tested-by: SPDK CI Jenkins Reviewed-by: Changpeng Liu Reviewed-by: GangCao Reviewed-by: Shuhei Matsumoto Reviewed-by: Ben Walker --- examples/nvmf/nvmf/Makefile | 1 + examples/nvmf/nvmf/nvmf.c | 71 ++++++++++++++++++++++++++++++++++++- 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/examples/nvmf/nvmf/Makefile b/examples/nvmf/nvmf/Makefile index 70563f1634..9c95660062 100644 --- a/examples/nvmf/nvmf/Makefile +++ b/examples/nvmf/nvmf/Makefile @@ -40,5 +40,6 @@ APP := nvmf C_SRCS := nvmf.c SPDK_LIB_LIST = $(ALL_MODULES_LIST) SPDK_LIB_LIST += nvmf thread util bdev conf copy rpc jsonrpc json log sock trace notify +SPDK_LIB_LIST += event event_bdev event_copy event_vmd include $(SPDK_ROOT_DIR)/mk/spdk.app.mk diff --git a/examples/nvmf/nvmf/nvmf.c b/examples/nvmf/nvmf/nvmf.c index 91ee7eec00..84afa64c7e 100644 --- a/examples/nvmf/nvmf/nvmf.c +++ b/examples/nvmf/nvmf/nvmf.c @@ -36,9 +36,18 @@ #include "spdk/event.h" #include "spdk/string.h" #include "spdk/thread.h" +#include "spdk/bdev.h" +#include "spdk/rpc.h" + +#include "spdk_internal/event.h" static const char *g_rpc_addr = SPDK_DEFAULT_RPC_ADDR; +enum nvmf_target_state { + NVMF_INIT_SUBSYSTEM = 0, + NVMF_FINI_SUBSYSTEM, +}; + struct nvmf_lw_thread { TAILQ_ENTRY(nvmf_lw_thread) link; }; @@ -54,8 +63,12 @@ TAILQ_HEAD(, nvmf_reactor) g_reactors = TAILQ_HEAD_INITIALIZER(g_reactors); static struct nvmf_reactor *g_master_reactor = NULL; static struct nvmf_reactor *g_next_reactor = NULL; +static struct spdk_thread *g_init_thread = NULL; static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; static bool g_reactors_exit = false; +static enum nvmf_target_state g_target_state; + +static void nvmf_target_advance_state(void); static void usage(char *program_name) @@ -285,10 +298,57 @@ nvmf_destroy_threads(void) fprintf(stdout, "nvmf threads destroy successfully\n"); } +static void +nvmf_subsystem_fini_done(void *cb_arg) +{ + fprintf(stdout, "bdev subsystem finish successfully\n"); + spdk_rpc_finish(); + g_reactors_exit = true; +} + +static void +nvmf_subsystem_init_done(int rc, void *cb_arg) +{ + fprintf(stdout, "bdev subsystem init successfully\n"); + spdk_rpc_initialize(g_rpc_addr); + spdk_rpc_set_state(SPDK_RPC_RUNTIME); + + g_target_state = NVMF_FINI_SUBSYSTEM; + nvmf_target_advance_state(); +} + +static void +nvmf_target_advance_state(void) +{ + enum nvmf_target_state prev_state; + + do { + prev_state = g_target_state; + + switch (g_target_state) { + case NVMF_INIT_SUBSYSTEM: + /* initlize the bdev layer */ + spdk_subsystem_init(nvmf_subsystem_init_done, NULL); + break; + case NVMF_FINI_SUBSYSTEM: + spdk_subsystem_fini(nvmf_subsystem_fini_done, NULL); + break; + } + } while (g_target_state != prev_state); +} + +static void +nvmf_target_app_start(void *arg) +{ + g_target_state = NVMF_INIT_SUBSYSTEM; + nvmf_target_advance_state(); +} + int main(int argc, char **argv) { int rc; struct spdk_env_opts opts; + struct nvmf_lw_thread *lw_thread; spdk_env_opts_init(&opts); opts.name = "nvmf-example"; @@ -307,8 +367,17 @@ int main(int argc, char **argv) rc = nvmf_init_threads(); assert(rc == 0); - g_reactors_exit = true; + /* Send a message to the thread assigned to the master reactor + * that continues initialization. This is how we bootstrap the + * program so that all code from here on is running on an SPDK thread. + */ + lw_thread = TAILQ_FIRST(&g_master_reactor->threads); + g_init_thread = spdk_thread_get_from_ctx(lw_thread); + assert(g_init_thread != NULL); + spdk_thread_send_msg(g_init_thread, nvmf_target_app_start, NULL); + nvmf_reactor_run(g_master_reactor); + spdk_env_thread_wait_all(); nvmf_destroy_threads(); return rc;