Skip to content

Commit 9bf2b97

Browse files
Keith Buschaxboe
authored andcommitted
NVMe: Fix reset/remove race
This fixes a scenario where device is present and being reset, but a request to unbind the driver occurs. A previous patch series addressing a device failure removal scenario flushed reset_work after controller disable to unblock reset_work waiting on a completion that wouldn't occur. This isn't safe as-is. The broken scenario can potentially be induced with: modprobe nvme && modprobe -r nvme To fix, the reset work is flushed immediately after setting the controller removing flag, and any subsequent reset will not proceed with controller initialization if the flag is set. The controller status must be polled while active, so the watchdog timer is also left active until the controller is disabled to cleanup requests that may be stuck during namespace removal. [Fixes: ff23a2a] Signed-off-by: Keith Busch <keith.busch@intel.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de> Reviewed-by: Sagi Grimberg <sagi@grimberg.me> Signed-off-by: Jens Axboe <axboe@fb.com>
1 parent c877ef8 commit 9bf2b97

File tree

1 file changed

+4
-2
lines changed

1 file changed

+4
-2
lines changed

drivers/nvme/host/pci.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1859,6 +1859,9 @@ static void nvme_reset_work(struct work_struct *work)
18591859
if (dev->ctrl.ctrl_config & NVME_CC_ENABLE)
18601860
nvme_dev_disable(dev, false);
18611861

1862+
if (test_bit(NVME_CTRL_REMOVING, &dev->flags))
1863+
goto out;
1864+
18621865
set_bit(NVME_CTRL_RESETTING, &dev->flags);
18631866

18641867
result = nvme_pci_enable(dev);
@@ -2078,11 +2081,10 @@ static void nvme_remove(struct pci_dev *pdev)
20782081
{
20792082
struct nvme_dev *dev = pci_get_drvdata(pdev);
20802083

2081-
del_timer_sync(&dev->watchdog_timer);
2082-
20832084
set_bit(NVME_CTRL_REMOVING, &dev->flags);
20842085
pci_set_drvdata(pdev, NULL);
20852086
flush_work(&dev->async_work);
2087+
flush_work(&dev->reset_work);
20862088
flush_work(&dev->scan_work);
20872089
nvme_remove_namespaces(&dev->ctrl);
20882090
nvme_uninit_ctrl(&dev->ctrl);

0 commit comments

Comments
 (0)