From 8fa8310be483ef5473828e3b9eda04337b5ba776 Mon Sep 17 00:00:00 2001 From: Liu Xiaodong Date: Wed, 31 Oct 2018 21:22:56 -0400 Subject: [PATCH] bdev_nvme: retain nvme_ctrl after delete_bdev When deleting bdev of NVMe type by delete_bdev rpc, if the bdev is the last one NVMe bdev of the NVMe controller, the NVMe controller will be deleted too. With this change, the nvme_ctrlr will be retained inside SPDK app after delete_bdev rpc. And the nvme_ctrlr can be deleted by delete_nvme_controller rpc. Change-Id: Icad6c24d342b9e4bcb69ec7a4b1a352c2df113f2 Signed-off-by: Liu Xiaodong Reviewed-on: https://review.gerrithub.io/431582 Tested-by: SPDK CI Jenkins Chandler-Test-Pool: SPDK Automated Test System Reviewed-by: Ben Walker Reviewed-by: Jim Harris --- lib/bdev/nvme/bdev_nvme.c | 35 +++++++++++++++++++++++++++-------- lib/bdev/nvme/bdev_nvme.h | 1 + 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/lib/bdev/nvme/bdev_nvme.c b/lib/bdev/nvme/bdev_nvme.c index 69e71fdf5..5ba18643e 100644 --- a/lib/bdev/nvme/bdev_nvme.c +++ b/lib/bdev/nvme/bdev_nvme.c @@ -260,6 +260,19 @@ bdev_nvme_unregister_cb(void *io_device) spdk_nvme_detach(ctrlr); } +static void +bdev_nvme_ctrlr_destruct(struct nvme_ctrlr *nvme_ctrlr) +{ + pthread_mutex_lock(&g_bdev_nvme_mutex); + TAILQ_REMOVE(&g_nvme_ctrlrs, nvme_ctrlr, tailq); + pthread_mutex_unlock(&g_bdev_nvme_mutex); + spdk_io_device_unregister(nvme_ctrlr->ctrlr, bdev_nvme_unregister_cb); + spdk_poller_unregister(&nvme_ctrlr->adminq_timer_poller); + free(nvme_ctrlr->name); + free(nvme_ctrlr->bdevs); + free(nvme_ctrlr); +} + static int bdev_nvme_destruct(void *ctx) { @@ -270,20 +283,16 @@ bdev_nvme_destruct(void *ctx) nvme_ctrlr->ref--; free(nvme_disk->disk.name); memset(nvme_disk, 0, sizeof(*nvme_disk)); - if (nvme_ctrlr->ref == 0) { - TAILQ_REMOVE(&g_nvme_ctrlrs, nvme_ctrlr, tailq); + if (nvme_ctrlr->ref == 0 && nvme_ctrlr->destruct) { + /* Clear destruct sign in case of reentering controller destruct */ + nvme_ctrlr->destruct = false; pthread_mutex_unlock(&g_bdev_nvme_mutex); - spdk_io_device_unregister(nvme_ctrlr->ctrlr, bdev_nvme_unregister_cb); - spdk_poller_unregister(&nvme_ctrlr->adminq_timer_poller); - free(nvme_ctrlr->name); - free(nvme_ctrlr->bdevs); - free(nvme_ctrlr); + bdev_nvme_ctrlr_destruct(nvme_ctrlr); return 0; } pthread_mutex_unlock(&g_bdev_nvme_mutex); return 0; - } static int @@ -1084,6 +1093,7 @@ remove_cb(void *cb_ctx, struct spdk_nvme_ctrlr *ctrlr) pthread_mutex_lock(&g_bdev_nvme_mutex); TAILQ_FOREACH(nvme_ctrlr, &g_nvme_ctrlrs, tailq) { if (nvme_ctrlr->ctrlr == ctrlr) { + nvme_ctrlr->destruct = true; pthread_mutex_unlock(&g_bdev_nvme_mutex); for (i = 0; i < nvme_ctrlr->num_ns; i++) { uint32_t nsid = i + 1; @@ -1094,6 +1104,15 @@ remove_cb(void *cb_ctx, struct spdk_nvme_ctrlr *ctrlr) spdk_bdev_unregister(&nvme_bdev->disk, NULL, NULL); } } + + pthread_mutex_lock(&g_bdev_nvme_mutex); + if (nvme_ctrlr->ref == 0 && nvme_ctrlr->destruct) { + nvme_ctrlr->destruct = false; + pthread_mutex_unlock(&g_bdev_nvme_mutex); + bdev_nvme_ctrlr_destruct(nvme_ctrlr); + } else { + pthread_mutex_unlock(&g_bdev_nvme_mutex); + } return; } } diff --git a/lib/bdev/nvme/bdev_nvme.h b/lib/bdev/nvme/bdev_nvme.h index 38e10e50f..9b6cffe0b 100644 --- a/lib/bdev/nvme/bdev_nvme.h +++ b/lib/bdev/nvme/bdev_nvme.h @@ -65,6 +65,7 @@ struct nvme_ctrlr { struct spdk_nvme_transport_id trid; char *name; int ref; + bool destruct; uint32_t num_ns; /** Array of bdevs indexed by nsid - 1 */ struct nvme_bdev *bdevs;