From 01a942dc6b4a1387e2e1c9661b7861172d948105 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 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/1253 (master) (cherry picked from commit ba7b55de870105dcb875bad55efec65151f54ff3) Change-Id: I20286814d904b8d5a9c5209bbb53663683a4e6b0 Signed-off-by: Tomasz Zawadzki Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/1305 Reviewed-by: Jim Harris Reviewed-by: Ben Walker Tested-by: SPDK CI Jenkins --- 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 27e50a83c..c25fcae55 100644 --- a/module/bdev/nvme/bdev_nvme.c +++ b/module/bdev/nvme/bdev_nvme.c @@ -428,6 +428,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 b30f26a45..91ca08ff9 100644 --- a/module/bdev/nvme/common.c +++ b/module/bdev/nvme/common.c @@ -130,10 +130,20 @@ nvme_bdev_unregister_cb(void *io_device) free(nvme_bdev_ctrlr); } -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); @@ -149,6 +159,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 0b0735510..653cfbaca 100644 --- a/module/bdev/nvme/common.h +++ b/module/bdev/nvme/common.h @@ -94,6 +94,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; @@ -150,7 +151,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);