diff --git a/app/vhost/vhost.c b/app/vhost/vhost.c index f0f5055a3..41f0510a4 100644 --- a/app/vhost/vhost.c +++ b/app/vhost/vhost.c @@ -105,8 +105,6 @@ main(int argc, char *argv[]) save_pid(g_pid_path); } - opts.shutdown_cb = spdk_vhost_shutdown_cb; - /* Blocks until the application is exiting */ rc = spdk_app_start(&opts, spdk_vhost_startup, (void *)g_socket_path, NULL); diff --git a/include/spdk/vhost.h b/include/spdk/vhost.h index 3f59d9ba1..60c3170fc 100644 --- a/include/spdk/vhost.h +++ b/include/spdk/vhost.h @@ -47,8 +47,10 @@ extern "C" { #endif +typedef void (*spdk_vhost_fini_cb)(void); + int spdk_vhost_init(void); -void spdk_vhost_fini(void); +void spdk_vhost_fini(spdk_vhost_fini_cb fini_cb); /** * Init vhost application. This is called once by SPDK app layer. diff --git a/lib/event/subsystems/vhost/vhost.c b/lib/event/subsystems/vhost/vhost.c index d8f6824f3..192ae8c03 100644 --- a/lib/event/subsystems/vhost/vhost.c +++ b/lib/event/subsystems/vhost/vhost.c @@ -47,11 +47,16 @@ spdk_vhost_subsystem_init(void) spdk_subsystem_init_next(rc); } +static void +spdk_vhost_subsystem_fini_done(void) +{ + spdk_subsystem_fini_next(); +} + static void spdk_vhost_subsystem_fini(void) { - spdk_vhost_fini(); - spdk_subsystem_fini_next(); + spdk_vhost_fini(spdk_vhost_subsystem_fini_done); } SPDK_SUBSYSTEM_REGISTER(vhost, spdk_vhost_subsystem_init, spdk_vhost_subsystem_fini, NULL) diff --git a/lib/vhost/vhost.c b/lib/vhost/vhost.c index 3b2089092..167450f9d 100644 --- a/lib/vhost/vhost.c +++ b/lib/vhost/vhost.c @@ -1125,6 +1125,12 @@ out: return rc; } +static void +spdk_vhost_kill_cb(void) +{ + spdk_app_stop(0); +} + void spdk_vhost_startup(void *arg1, void *arg2) { @@ -1159,13 +1165,7 @@ spdk_vhost_startup(void *arg1, void *arg2) return; out: - spdk_vhost_shutdown_cb(); -} - -static void -session_app_stop(void *arg1, void *arg2) -{ - spdk_app_stop(0); + spdk_vhost_fini(spdk_vhost_kill_cb); } static void * @@ -1188,26 +1188,6 @@ session_shutdown(void *arg) return NULL; } -/* - * When we receive a INT signal. Execute shutdown in separate thread to avoid deadlock. - */ -void -spdk_vhost_shutdown_cb(void) -{ - pthread_t tid; - int rc; - struct spdk_event *vhost_app_stop; - - vhost_app_stop = spdk_event_allocate(spdk_env_get_current_core(), session_app_stop, NULL, NULL); - - rc = pthread_create(&tid, NULL, &session_shutdown, vhost_app_stop); - if (rc < 0) { - SPDK_ERRLOG("Failed to start session shutdown thread (%d): %s\n", rc, spdk_strerror(rc)); - abort(); - } - pthread_detach(tid); -} - void spdk_vhost_dump_config_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w) @@ -1357,10 +1337,34 @@ spdk_vhost_init(void) return 0; } -void -spdk_vhost_fini(void) +static void +_spdk_vhost_fini(void *arg1, void *arg2) { + spdk_vhost_fini_cb fini_cb = arg1; + free(g_num_ctrlrs); + fini_cb(); +} + +void +spdk_vhost_fini(spdk_vhost_fini_cb fini_cb) +{ + pthread_t tid; + int rc; + struct spdk_event *fini_ev; + + fini_ev = spdk_event_allocate(spdk_env_get_current_core(), _spdk_vhost_fini, fini_cb, NULL); + + /* rte_vhost API for removing sockets is not asynchronous. Since it may call SPDK + * ops for stopping a device or removing a connection, we need to call it from + * a separate thread to avoid deadlock. + */ + rc = pthread_create(&tid, NULL, &session_shutdown, fini_ev); + if (rc < 0) { + SPDK_ERRLOG("Failed to start session shutdown thread (%d): %s\n", rc, spdk_strerror(rc)); + abort(); + } + pthread_detach(tid); } SPDK_LOG_REGISTER_COMPONENT("vhost_ring", SPDK_LOG_VHOST_RING)