diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index 01a68250f8682de11c3a853e80f0edfbfb7f7d4f..22761a6c34aa6edeae71a38db5ced7260228664a 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -2931,6 +2931,18 @@ static int nvme_dev_resume(struct nvme_dev *dev) return 0; } +static void nvme_dead_ctrl(struct nvme_dev *dev) +{ + dev_warn(dev->dev, "Device failed to resume\n"); + kref_get(&dev->kref); + if (IS_ERR(kthread_run(nvme_remove_dead_ctrl, dev, "nvme%d", + dev->instance))) { + dev_err(dev->dev, + "Failed to start controller remove task\n"); + kref_put(&dev->kref, nvme_free_dev); + } +} + static void nvme_dev_reset(struct nvme_dev *dev) { bool in_probe = work_busy(&dev->probe_work); @@ -2944,14 +2956,7 @@ static void nvme_dev_reset(struct nvme_dev *dev) /* Fail this device if reset occured during probe to avoid * infinite initialization loops. */ if (in_probe) { - dev_warn(dev->dev, "Device failed to resume\n"); - kref_get(&dev->kref); - if (IS_ERR(kthread_run(nvme_remove_dead_ctrl, dev, "nvme%d", - dev->instance))) { - dev_err(dev->dev, - "Failed to start controller remove task\n"); - kref_put(&dev->kref, nvme_free_dev); - } + nvme_dead_ctrl(dev); return; } /* Schedule device resume asynchronously so the reset work is available @@ -3086,16 +3091,8 @@ static void nvme_async_probe(struct work_struct *work) { struct nvme_dev *dev = container_of(work, struct nvme_dev, probe_work); - if (nvme_dev_resume(dev)) - goto reset; - return; - reset: - spin_lock(&dev_list_lock); - if (!work_busy(&dev->reset_work)) { - dev->reset_workfn = nvme_reset_failed_dev; - queue_work(nvme_workq, &dev->reset_work); - } - spin_unlock(&dev_list_lock); + if (nvme_dev_resume(dev) && !work_busy(&dev->reset_work)) + nvme_dead_ctrl(dev); } static void nvme_reset_notify(struct pci_dev *pdev, bool prepare)