From: Christoph Hellwig Date: Sat, 3 Oct 2015 07:49:23 +0000 (+0200) Subject: nvme: merge nvme_dev_start, nvme_dev_resume and nvme_async_probe X-Git-Tag: v4.1.12-92~126^2~232 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=19d6a1b729e6f367c58810f5f6787d142c80a2de;p=users%2Fjedix%2Flinux-maple.git nvme: merge nvme_dev_start, nvme_dev_resume and nvme_async_probe And give the resulting function a sensible name. This keeps all the error handling in a single place and will allow for further improvements to it. Signed-off-by: Christoph Hellwig Reviewed-by: Keith Busch Signed-off-by: Jens Axboe (cherry picked from commit 3cf519b5a8d4d067e3de19736283c9414402d3a2) Orabug: 22620486 Signed-off-by: Jason Luo --- diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index f266ef881d063..5190a7d3dcd0f 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -89,6 +89,7 @@ static struct class *nvme_class; static int __nvme_reset(struct nvme_dev *dev); static int nvme_reset(struct nvme_dev *dev); static int nvme_process_cq(struct nvme_queue *nvmeq); +static void nvme_dead_ctrl(struct nvme_dev *dev); struct async_cmd_info { struct kthread_work work; @@ -2951,28 +2952,29 @@ static const struct file_operations nvme_dev_fops = { static void nvme_set_irq_hints(struct nvme_dev *dev) { - struct nvme_queue *nvmeq; - int i; + struct nvme_queue *nvmeq; + int i; - for (i = 0; i < dev->online_queues; i++) { - nvmeq = dev->queues[i]; + for (i = 0; i < dev->online_queues; i++) { + nvmeq = dev->queues[i]; - if (!nvmeq->hctx) - continue; + if (!nvmeq->hctx) + continue; - irq_set_affinity_hint(dev->entry[nvmeq->cq_vector].vector, - nvmeq->hctx->cpumask); - } + irq_set_affinity_hint(dev->entry[nvmeq->cq_vector].vector, + nvmeq->hctx->cpumask); + } } -static int nvme_dev_start(struct nvme_dev *dev) +static void nvme_probe_work(struct work_struct *work) { - int result; + struct nvme_dev *dev = container_of(work, struct nvme_dev, probe_work); bool start_thread = false; + int result; result = nvme_dev_map(dev); if (result) - return result; + goto out; result = nvme_configure_admin_queue(dev); if (result) @@ -3009,7 +3011,17 @@ static int nvme_dev_start(struct nvme_dev *dev) nvme_set_irq_hints(dev); dev->event_limit = 1; - return result; + + if (dev->online_queues < 2) { + dev_warn(dev->dev, "IO queues not created\n"); + nvme_free_queues(dev, 1); + nvme_dev_remove(dev); + } else { + nvme_unfreeze_queues(dev); + nvme_dev_add(dev); + } + + return; free_tags: nvme_dev_remove_admin(dev); @@ -3020,7 +3032,9 @@ static int nvme_dev_start(struct nvme_dev *dev) nvme_dev_list_remove(dev); unmap: nvme_dev_unmap(dev); - return result; + out: + if (!work_busy(&dev->reset_work)) + nvme_dead_ctrl(dev); } static int nvme_remove_dead_ctrl(void *arg) @@ -3034,25 +3048,6 @@ static int nvme_remove_dead_ctrl(void *arg) return 0; } -static int nvme_dev_resume(struct nvme_dev *dev) -{ - int ret; - - ret = nvme_dev_start(dev); - if (ret) - return ret; - if (dev->online_queues < 2) { - dev_warn(dev->dev, "IO queues not created\n"); - nvme_free_queues(dev, 1); - nvme_dev_remove(dev); - } else { - nvme_unfreeze_queues(dev); - nvme_dev_add(dev); - nvme_set_irq_hints(dev); - } - return 0; -} - static void nvme_dead_ctrl(struct nvme_dev *dev) { dev_warn(dev->dev, "Device failed to resume\n"); @@ -3131,7 +3126,6 @@ static ssize_t nvme_sysfs_reset(struct device *dev, } static DEVICE_ATTR(reset_controller, S_IWUSR, NULL, nvme_sysfs_reset); -static void nvme_async_probe(struct work_struct *work); static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) { int node, result = -ENOMEM; @@ -3182,7 +3176,7 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) INIT_LIST_HEAD(&dev->node); INIT_WORK(&dev->scan_work, nvme_dev_scan); - INIT_WORK(&dev->probe_work, nvme_async_probe); + INIT_WORK(&dev->probe_work, nvme_probe_work); schedule_work(&dev->probe_work); return 0; @@ -3202,14 +3196,6 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) return result; } -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) && !work_busy(&dev->reset_work)) - nvme_dead_ctrl(dev); -} - static void nvme_reset_notify(struct pci_dev *pdev, bool prepare) { struct nvme_dev *dev = pci_get_drvdata(pdev);