Skip to content

Commit 54718ee

Browse files
hreineckegregkh
authored andcommitted
nvme: drop scan_lock and always kick requeue list when removing namespaces
[ Upstream commit 2b81a5f ] When reading the partition table on initial scan hits an I/O error the I/O will hang with the scan_mutex held: [<0>] do_read_cache_page+0x49b/0x790 [<0>] read_part_sector+0x39/0xe0 [<0>] read_lba+0xf9/0x1d0 [<0>] efi_partition+0xf1/0x7f0 [<0>] bdev_disk_changed+0x1ee/0x550 [<0>] blkdev_get_whole+0x81/0x90 [<0>] blkdev_get_by_dev+0x128/0x2e0 [<0>] device_add_disk+0x377/0x3c0 [<0>] nvme_mpath_set_live+0x130/0x1b0 [nvme_core] [<0>] nvme_mpath_add_disk+0x150/0x160 [nvme_core] [<0>] nvme_alloc_ns+0x417/0x950 [nvme_core] [<0>] nvme_validate_or_alloc_ns+0xe9/0x1e0 [nvme_core] [<0>] nvme_scan_work+0x168/0x310 [nvme_core] [<0>] process_one_work+0x231/0x420 and trying to delete the controller will deadlock as it tries to grab the scan mutex: [<0>] nvme_mpath_clear_ctrl_paths+0x25/0x80 [nvme_core] [<0>] nvme_remove_namespaces+0x31/0xf0 [nvme_core] [<0>] nvme_do_delete_ctrl+0x4b/0x80 [nvme_core] As we're now properly ordering the namespace list there is no need to hold the scan_mutex in nvme_mpath_clear_ctrl_paths() anymore. And we always need to kick the requeue list as the path will be marked as unusable and I/O will be requeued _without_ a current path. Signed-off-by: Hannes Reinecke <[email protected]> Reviewed-by: Keith Busch <[email protected]> Reviewed-by: Sagi Grimberg <[email protected]> Signed-off-by: Christoph Hellwig <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 0703920 commit 54718ee

File tree

1 file changed

+4
-5
lines changed

1 file changed

+4
-5
lines changed

drivers/nvme/host/multipath.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -138,13 +138,12 @@ void nvme_mpath_clear_ctrl_paths(struct nvme_ctrl *ctrl)
138138
{
139139
struct nvme_ns *ns;
140140

141-
mutex_lock(&ctrl->scan_lock);
142141
down_read(&ctrl->namespaces_rwsem);
143-
list_for_each_entry(ns, &ctrl->namespaces, list)
144-
if (nvme_mpath_clear_current_path(ns))
145-
kblockd_schedule_work(&ns->head->requeue_work);
142+
list_for_each_entry(ns, &ctrl->namespaces, list) {
143+
nvme_mpath_clear_current_path(ns);
144+
kblockd_schedule_work(&ns->head->requeue_work);
145+
}
146146
up_read(&ctrl->namespaces_rwsem);
147-
mutex_unlock(&ctrl->scan_lock);
148147
}
149148

150149
void nvme_mpath_revalidate_paths(struct nvme_ns *ns)

0 commit comments

Comments
 (0)