lkml.org 
[lkml]   [2021]   [Nov]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.15 281/917] nvme: drop scan_lock and always kick requeue list when removing namespaces
    Date
    From: Hannes Reinecke <hare@suse.de>

    [ Upstream commit 2b81a5f015199f3d585ce710190a9e87714d3c1e ]

    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 <hare@suse.de>
    Reviewed-by: Keith Busch <kbusch@kernel.org>
    Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
    Signed-off-by: Christoph Hellwig <hch@lst.de>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/nvme/host/multipath.c | 9 ++++-----
    1 file changed, 4 insertions(+), 5 deletions(-)

    diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
    index fba06618c6c23..2f76969408b27 100644
    --- a/drivers/nvme/host/multipath.c
    +++ b/drivers/nvme/host/multipath.c
    @@ -138,13 +138,12 @@ void nvme_mpath_clear_ctrl_paths(struct nvme_ctrl *ctrl)
    {
    struct nvme_ns *ns;

    - mutex_lock(&ctrl->scan_lock);
    down_read(&ctrl->namespaces_rwsem);
    - list_for_each_entry(ns, &ctrl->namespaces, list)
    - if (nvme_mpath_clear_current_path(ns))
    - kblockd_schedule_work(&ns->head->requeue_work);
    + list_for_each_entry(ns, &ctrl->namespaces, list) {
    + nvme_mpath_clear_current_path(ns);
    + kblockd_schedule_work(&ns->head->requeue_work);
    + }
    up_read(&ctrl->namespaces_rwsem);
    - mutex_unlock(&ctrl->scan_lock);
    }

    void nvme_mpath_revalidate_paths(struct nvme_ns *ns)
    --
    2.33.0


    \
     
     \ /
      Last update: 2021-11-16 00:35    [W:2.615 / U:2.120 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site