]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
nvme-pci: fix hot removal during error handling
authorKeith Busch <keith.busch@intel.com>
Mon, 15 Oct 2018 16:19:06 +0000 (10:19 -0600)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 1 Dec 2019 08:16:30 +0000 (09:16 +0100)
[ Upstream commit cb4bfda62afa25b4eee3d635d33fccdd9485dd7c ]

A removal waits for the reset_work to complete. If a surprise removal
occurs around the same time as an error triggered controller reset, and
reset work happened to dispatch a command to the removed controller, the
command won't be recovered since the timeout work doesn't do anything
during error recovery. We wouldn't want to wait for timeout handling
anyway, so this patch fixes this by disabling the controller and killing
admin queues prior to syncing with the reset_work.

Signed-off-by: Keith Busch <keith.busch@intel.com>
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/pci.c

index a64a8bca0d5b9dcfe9056f9207568f2a3dd1e0b7..9479c0db08f62566aeee3c789a6d146a4c7f5112 100644 (file)
@@ -2583,13 +2583,12 @@ static void nvme_remove(struct pci_dev *pdev)
        struct nvme_dev *dev = pci_get_drvdata(pdev);
 
        nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_DELETING);
-
-       cancel_work_sync(&dev->ctrl.reset_work);
        pci_set_drvdata(pdev, NULL);
 
        if (!pci_device_is_present(pdev)) {
                nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_DEAD);
                nvme_dev_disable(dev, true);
+               nvme_dev_remove_admin(dev);
        }
 
        flush_work(&dev->ctrl.reset_work);