Commit 10ea1659 authored by Jacek Kalwas's avatar Jacek Kalwas Committed by Tomasz Zawadzki
Browse files

bdev/nvme: prevent ns populate before ctrlr registration



This is a race between receiving the ANA log page callback and
controller registration. It can lead to obtaining an I/O channel on
an not registered controller.

If an AER with a namespace change notification arrives before
nvme_ctrlr_init_ana_log_page_done, the following flow might occur:

nvme_bdev_add_ns -> nvme_bdev_for_each_channel ->
bdev_nvme_add_io_path -> _bdev_nvme_add_io_path ->
spdk_get_io_channel

or

spdk_bdev_get_io_channel -> (...) -> bdev_nvme_create_bdev_channel_cb ->
_bdev_nvme_add_io_path -> spdk_get_io_channel

Fix by registering the AER callback after the controller is registered.

Change-Id: Ia91df81e9dadb850a0032c43d9bb24edaaab1393
Signed-off-by: default avatarJacek Kalwas <jacek.kalwas@nutanix.com>
Reviewed-on: https://review.spdk.io/c/spdk/spdk/+/26925


Tested-by: default avatarSPDK Automated Test System <spdkbot@gmail.com>
Reviewed-by: default avatarTomasz Zawadzki <tomasz@tzawadzki.com>
Reviewed-by: default avatarShuhei Matsumoto <smatsumoto@nvidia.com>
Community-CI: Mellanox Build Bot
parent 0b1cdd21
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -5803,6 +5803,11 @@ nvme_ctrlr_create_done(struct nvme_ctrlr *nvme_ctrlr,
				sizeof(struct nvme_ctrlr_channel),
				nvme_ctrlr->nbdev_ctrlr->name);

	/* AER callback is registered late to prevent getting the I/O channel
	 * on an unregistered controller during namespace population. */
	spdk_nvme_ctrlr_register_aer_callback(nvme_ctrlr->ctrlr, aer_cb, nvme_ctrlr);

	/* Populate namespaces for the first time. */
	nvme_ctrlr_populate_namespaces(nvme_ctrlr, ctx);

	if (g_hotplug_poller == NULL) {
@@ -6109,7 +6114,6 @@ nvme_ctrlr_create(struct spdk_nvme_ctrlr *ctrlr,
				adm_timeout_us, timeout_cb, nvme_ctrlr);
	}

	spdk_nvme_ctrlr_register_aer_callback(ctrlr, aer_cb, nvme_ctrlr);
	spdk_nvme_ctrlr_set_remove_cb(ctrlr, remove_cb, nvme_ctrlr);

	if (spdk_nvme_ctrlr_get_flags(ctrlr) &