Skip to content

Commit 1ff9eb2

Browse files
committed
bdev/nvme: do not create bdev_nvme on namespace no longer active
Despite AER handling being synchronous in nvme library, changes on target side can happen while AER is being handled. Order of operations for AER is: read log page, identify controller, identify every active namespace. Right now the buffer from log page is unused, but further down the series it will be used to select which namespaces to send identify to. This means that the state could have changed after reading the log page, but before identifying controller. Resulting in more active namespaces, than we will be sending identify to. We can be sure that target has another AER pending for that namespace, with log page containing it. Yet on the initiator side we cannot assume every nsdata for every active namespace was filled while processing a single AER. After using the log page in following patches, this backtrace can be seen: #0 0x000000528f50 in spdk_divide_round_up /spdk/aer_handling/include/spdk/util.h:176 #1 0x00000052d6b0 in raid_bdev_load_base_bdev_superblock /spdk/aer_handling/module/bdev/raid/bdev_raid_sb.c:290 #2 0x0000005253f4 in raid_bdev_examine_load_sb /spdk/aer_handling/module/bdev/raid/bdev_raid.c:3874 #3 0x000000525810 in raid_bdev_examine /spdk/aer_handling/module/bdev/raid/bdev_raid.c:3943 #4 0x000000d72238 in bdev_examine /spdk/aer_handling/lib/bdev/bdev.c:762 #5 0x000000ddac74 in spdk_bdev_register /spdk/aer_handling/lib/bdev/bdev.c:9116 #6 0x0000004684e4 in nvme_bdev_create /spdk/aer_handling/module/bdev/nvme/bdev_nvme.c:4710 #7 0x00000046d1c4 in nvme_ctrlr_populate_namespace /spdk/aer_handling/module/bdev/nvme/bdev_nvme.c:5017 #8 0x00000046fdac in nvme_ctrlr_populate_namespaces /spdk/aer_handling/module/bdev/nvme/bdev_nvme.c:5195 #9 0x0000004743a4 in aer_cb /spdk/aer_handling/module/bdev/nvme/bdev_nvme.c:5648 #10 0x000000b6892c in nvme_ctrlr_process_async_event_finish /spdk/aer_handling/lib/nvme/nvme_ctrlr.c:3198 #11 0x000000b6a3e0 in nvme_ctrlr_process_async_event /spdk/aer_handling/lib/nvme/nvme_ctrlr.c:3362 #12 0x000000b6b314 in nvme_ctrlr_complete_queued_async_events /spdk/aer_handling/lib/nvme/nvme_ctrlr.c:3398 #13 0x000000b7cff4 in spdk_nvme_ctrlr_process_admin_completions /spdk/aer_handling/lib/nvme/nvme_ctrlr.c:4622 #14 0x0000004428cc in bdev_nvme_poll_adminq /spdk/aer_handling/module/bdev/nvme/bdev_nvme.c:1872 A simple fix for now is to skip namespaces that do not have nsdata filled out, by using a function that actually checks it - spdk_nvme_ns_is_active(). Change-Id: I07a214c980c22dac4085d2ca3354bd2ba8046687 Signed-off-by: Tomasz Zawadzki <[email protected]> Reviewed-on: https://review.spdk.io/c/spdk/spdk/+/26496 Reviewed-by: Jacek Kalwas <[email protected]> Reviewed-by: Ben Walker <[email protected]> Reviewed-by: Jim Harris <[email protected]> Tested-by: SPDK Automated Test System <[email protected]> Community-CI: Mellanox Build Bot
1 parent 7e9386d commit 1ff9eb2

File tree

2 files changed

+9
-0
lines changed

2 files changed

+9
-0
lines changed

module/bdev/nvme/bdev_nvme.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5174,6 +5174,13 @@ nvme_ctrlr_populate_namespaces(struct nvme_ctrlr *nvme_ctrlr,
51745174

51755175
/* Found a new one */
51765176

5177+
ns = spdk_nvme_ctrlr_get_ns(nvme_ctrlr->ctrlr, nsid);
5178+
if (ns == NULL || !spdk_nvme_ns_is_active(ns)) {
5179+
/* Namespace was present during identify controller,
5180+
* but identify ns was not yet sent. */
5181+
continue;
5182+
}
5183+
51775184
nvme_ns = nvme_ns_alloc();
51785185
if (nvme_ns == NULL) {
51795186
NVME_CTRLR_ERRLOG(nvme_ctrlr, "Failed to allocate namespace\n");

test/unit/lib/bdev/nvme/bdev_nvme.c/bdev_nvme_ut.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ DEFINE_STUB(spdk_nvme_ctrlr_get_admin_qp_fd, int, (struct spdk_nvme_ctrlr *ctrlr
9090
DEFINE_STUB(spdk_nvme_poll_group_set_interrupt_callback, int,
9191
(struct spdk_nvme_poll_group *group,
9292
spdk_nvme_poll_group_interrupt_cb cb_fn, void *ctx), 0);
93+
DEFINE_STUB(spdk_nvme_ns_is_active, bool, (struct spdk_nvme_ns *ns), true);
94+
9395
int
9496
spdk_nvme_ctrlr_get_memory_domains(const struct spdk_nvme_ctrlr *ctrlr,
9597
struct spdk_memory_domain **domains, int array_size)

0 commit comments

Comments
 (0)