From 4b0cce4c460eb9338a6ae0f0a62f49f96bc09492 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 26 Nov 2015 12:35:49 +0100 Subject: [PATCH] nvme: remove dead controllers from a work item Compared to the kthread this gives us multiple call prevention for free. Signed-off-by: Christoph Hellwig Signed-off-by: Keith Busch Signed-off-by: Jens Axboe (cherry picked from commit 5c8809e650772be87ba04595a8ccf278bab7b543) Orabug: 25130845 Signed-off-by: Ashok Vairavan Reviewed-by: Martin K. Petersen --- drivers/nvme/host/pci.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 781d8ec2cd1b..21c1c460c46f 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -1922,19 +1922,26 @@ static void nvme_reset_work(struct work_struct *work) return; out: - nvme_remove_dead_ctrl(dev, result); + nvme_remove_dead_ctrl(dev); } -static int nvme_remove_dead_ctrl(void *arg) +static void nvme_remove_dead_ctrl_work(struct work_struct *work) { - struct nvme_dev *dev = (struct nvme_dev *)arg; + struct nvme_dev *dev = container_of(work, struct nvme_dev, remove_work); struct pci_dev *pdev = to_pci_dev(dev->dev); nvme_kill_queues(&dev->ctrl); if (pci_get_drvdata(pdev)) pci_stop_and_remove_bus_device_locked(pdev); nvme_put_ctrl(&dev->ctrl); - return 0; +} + +static void nvme_remove_dead_ctrl(struct nvme_dev *dev) +{ + dev_warn(dev->dev, "Removing after probe failure\n"); + kref_get(&dev->ctrl.kref); + if (!schedule_work(&dev->remove_work)) + nvme_put_ctrl(&dev->ctrl); } static int nvme_reset(struct nvme_dev *dev) -- 2.50.1