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 <james.r.harris@intel.com>
Change-Id: I20286814d904b8d5a9c5209bbb53663683a4e6b0

Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/1253
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
This commit is contained in:
Jim Harris 2020-03-12 10:42:25 -07:00 committed by Tomasz Zawadzki
parent 2571cbd807
commit ba7b55de87
3 changed files with 23 additions and 2 deletions

View File

@ -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 {

View File

@ -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

View File

@ -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);