diff --git a/lib/nvmf/subsystem.c b/lib/nvmf/subsystem.c index 296183e2a..59d5418b0 100644 --- a/lib/nvmf/subsystem.c +++ b/lib/nvmf/subsystem.c @@ -128,17 +128,16 @@ nvmf_create_subsystem(int num, const char *name, return subsystem; } -int -nvmf_delete_subsystem(struct spdk_nvmf_subsystem *subsystem) +static void +nvmf_delete_subsystem_poller_unreg(struct spdk_event *event) { + struct spdk_nvmf_subsystem *subsystem = spdk_event_get_arg1(event); struct spdk_nvmf_listen_addr *listen_addr, *listen_addr_tmp; struct spdk_nvmf_host *host, *host_tmp; - if (subsystem == NULL) { - SPDK_TRACELOG(SPDK_TRACE_NVMF, - "nvmf_delete_subsystem: there is no subsystem\n"); - return 0; - } + /* + * The poller has been unregistered, so now the memory can be freed. + */ TAILQ_FOREACH_SAFE(listen_addr, &subsystem->listen_addrs, link, listen_addr_tmp) { TAILQ_REMOVE(&subsystem->listen_addrs, listen_addr, link); @@ -166,6 +165,27 @@ nvmf_delete_subsystem(struct spdk_nvmf_subsystem *subsystem) TAILQ_REMOVE(&g_subsystems, subsystem, entries); free(subsystem); +} + +int +nvmf_delete_subsystem(struct spdk_nvmf_subsystem *subsystem) +{ + struct spdk_event *event; + + if (subsystem == NULL) { + SPDK_TRACELOG(SPDK_TRACE_NVMF, + "nvmf_delete_subsystem: there is no subsystem\n"); + return 0; + } + + /* + * Unregister the poller - this starts a chain of events that will eventually free + * the subsystem's memory. + */ + event = spdk_event_allocate(spdk_app_get_current_core(), nvmf_delete_subsystem_poller_unreg, + subsystem, NULL, NULL); + spdk_poller_unregister(&subsystem->poller, event); + return 0; } diff --git a/test/lib/nvmf/subsystem/subsystem_ut.c b/test/lib/nvmf/subsystem/subsystem_ut.c index 4eb184fd2..53f3b99fb 100644 --- a/test/lib/nvmf/subsystem/subsystem_ut.c +++ b/test/lib/nvmf/subsystem/subsystem_ut.c @@ -47,12 +47,30 @@ SPDK_LOG_REGISTER_TRACE_FLAG("nvmf", SPDK_TRACE_NVMF) struct spdk_nvmf_globals g_nvmf_tgt; +uint32_t +spdk_app_get_current_core(void) +{ + return 0; +} + +struct spdk_event *spdk_event_allocate(uint32_t lcore, spdk_event_fn fn, + void *arg1, void *arg2, + spdk_event_t next) +{ + return NULL; +} + void spdk_poller_register(struct spdk_poller **ppoller, spdk_poller_fn fn, void *arg, uint32_t lcore, struct spdk_event *complete, uint64_t period_microseconds) { } +void spdk_poller_unregister(struct spdk_poller **ppoller, + struct spdk_event *complete) +{ +} + int32_t spdk_nvme_ctrlr_process_admin_completions(struct spdk_nvme_ctrlr *ctrlr) {