From ba7b55de870105dcb875bad55efec65151f54ff3 Mon Sep 17 00:00:00 2001 From: Jim Harris Date: Thu, 12 Mar 2020 10:42:25 -0700 Subject: [PATCH] bdev/nvme: do not destruct ctrlr if reset is in progress The adminq poller could get a failure if the ctrlr has already been hot removed, which starts a reset. But while the for_each_channel is running for the reset, the hotplug poller could run and start the destruct process. If the ctrlr is deleted before the for_each_channel completes, we will try to call spdk_nvme_ctrlr_reset() on a deleted controller. While here, also add a check to skip the reset if the controller is already in the process of being removed. Fixes #1273. Signed-off-by: Jim Harris Change-Id: I20286814d904b8d5a9c5209bbb53663683a4e6b0 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/1253 Tested-by: SPDK CI Jenkins Reviewed-by: Changpeng Liu Reviewed-by: Shuhei Matsumoto Reviewed-by: Aleksey Marchuk --- module/bdev/nvme/bdev_nvme.c | 9 +++++++++ module/bdev/nvme/common.c | 13 ++++++++++++- module/bdev/nvme/common.h | 3 ++- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/module/bdev/nvme/bdev_nvme.c b/module/bdev/nvme/bdev_nvme.c index 2858a1493..4d5c3c039 100644 --- a/module/bdev/nvme/bdev_nvme.c +++ b/module/bdev/nvme/bdev_nvme.c @@ -429,6 +429,15 @@ bdev_nvme_reset(struct nvme_bdev_ctrlr *nvme_bdev_ctrlr, struct nvme_bdev_io *bi struct nvme_io_channel *nvme_ch; pthread_mutex_lock(&g_bdev_nvme_mutex); + if (nvme_bdev_ctrlr->destruct) { + /* Don't bother resetting if the controller is in the process of being destructed. */ + if (bio) { + spdk_bdev_io_complete(spdk_bdev_io_from_ctx(bio), SPDK_BDEV_IO_STATUS_FAILED); + } + pthread_mutex_unlock(&g_bdev_nvme_mutex); + return 0; + } + if (!nvme_bdev_ctrlr->resetting) { nvme_bdev_ctrlr->resetting = true; } else { diff --git a/module/bdev/nvme/common.c b/module/bdev/nvme/common.c index fce521213..8f8296ea2 100644 --- a/module/bdev/nvme/common.c +++ b/module/bdev/nvme/common.c @@ -140,10 +140,20 @@ nvme_bdev_unregister_cb(void *io_device) pthread_mutex_unlock(&g_bdev_nvme_mutex); } -void +int nvme_bdev_ctrlr_destruct(struct nvme_bdev_ctrlr *nvme_bdev_ctrlr) { assert(nvme_bdev_ctrlr->destruct); + pthread_mutex_lock(&g_bdev_nvme_mutex); + if (nvme_bdev_ctrlr->resetting) { + nvme_bdev_ctrlr->destruct_poller = + spdk_poller_register((spdk_poller_fn)nvme_bdev_ctrlr_destruct, nvme_bdev_ctrlr, 1000); + pthread_mutex_unlock(&g_bdev_nvme_mutex); + return 1; + } + pthread_mutex_unlock(&g_bdev_nvme_mutex); + + spdk_poller_unregister(&nvme_bdev_ctrlr->destruct_poller); if (nvme_bdev_ctrlr->opal_dev) { if (nvme_bdev_ctrlr->opal_poller != NULL) { spdk_poller_unregister(&nvme_bdev_ctrlr->opal_poller); @@ -159,6 +169,7 @@ nvme_bdev_ctrlr_destruct(struct nvme_bdev_ctrlr *nvme_bdev_ctrlr) } spdk_io_device_unregister(nvme_bdev_ctrlr, nvme_bdev_unregister_cb); + return 1; } void diff --git a/module/bdev/nvme/common.h b/module/bdev/nvme/common.h index 96cd6d0fc..01e576060 100644 --- a/module/bdev/nvme/common.h +++ b/module/bdev/nvme/common.h @@ -95,6 +95,7 @@ struct nvme_bdev_ctrlr { struct spdk_poller *opal_poller; struct spdk_poller *adminq_timer_poller; + struct spdk_poller *destruct_poller; struct ocssd_bdev_ctrlr *ocssd_ctrlr; @@ -152,7 +153,7 @@ struct nvme_bdev_ctrlr *nvme_bdev_next_ctrlr(struct nvme_bdev_ctrlr *prev); void nvme_bdev_dump_trid_json(struct spdk_nvme_transport_id *trid, struct spdk_json_write_ctx *w); -void nvme_bdev_ctrlr_destruct(struct nvme_bdev_ctrlr *nvme_bdev_ctrlr); +int nvme_bdev_ctrlr_destruct(struct nvme_bdev_ctrlr *nvme_bdev_ctrlr); void nvme_bdev_attach_bdev_to_ns(struct nvme_bdev_ns *nvme_ns, struct nvme_bdev *nvme_disk); void nvme_bdev_detach_bdev_from_ns(struct nvme_bdev *nvme_disk);