Commit ba7b55de authored by Jim Harris's avatar Jim Harris Committed by Tomasz Zawadzki
Browse files

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

Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/1253


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@mellanox.com>
parent 2571cbd8
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -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 {
+12 −1
Original line number Diff line number Diff line
@@ -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
+2 −1
Original line number Diff line number Diff line
@@ -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);