summaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorKeith Busch <keith.busch@intel.com>2015-06-18 15:36:39 -0400
committerJens Axboe <axboe@fb.com>2015-06-27 13:42:53 -0400
commitde3eff2bad56f0a29d3915105223d368f2bbc94e (patch)
tree628ca789a3036a36fd1600f4ae511cfbb3aa1e0e /drivers/block
parentffe7704d59025ce7a37525146d44b6a79510fc8e (diff)
NVMe: Failed controller initialization fixes
This fixes an infinite device reset loop that may occur on devices that fail initialization. If the drive fails to become ready for any reason that does not involve an admin command timeout, the probe task should assume the drive is unavailable and remove it from the topology. In the case an admin command times out during device probing, the driver's existing reset action will handle removing the drive. Signed-off-by: Keith Busch <keith.busch@intel.com> Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/nvme-core.c33
1 files changed, 15 insertions, 18 deletions
diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c
index 01a68250f868..22761a6c34aa 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)
2931 return 0; 2931 return 0;
2932} 2932}
2933 2933
2934static void nvme_dead_ctrl(struct nvme_dev *dev)
2935{
2936 dev_warn(dev->dev, "Device failed to resume\n");
2937 kref_get(&dev->kref);
2938 if (IS_ERR(kthread_run(nvme_remove_dead_ctrl, dev, "nvme%d",
2939 dev->instance))) {
2940 dev_err(dev->dev,
2941 "Failed to start controller remove task\n");
2942 kref_put(&dev->kref, nvme_free_dev);
2943 }
2944}
2945
2934static void nvme_dev_reset(struct nvme_dev *dev) 2946static void nvme_dev_reset(struct nvme_dev *dev)
2935{ 2947{
2936 bool in_probe = work_busy(&dev->probe_work); 2948 bool in_probe = work_busy(&dev->probe_work);
@@ -2944,14 +2956,7 @@ static void nvme_dev_reset(struct nvme_dev *dev)
2944 /* Fail this device if reset occured during probe to avoid 2956 /* Fail this device if reset occured during probe to avoid
2945 * infinite initialization loops. */ 2957 * infinite initialization loops. */
2946 if (in_probe) { 2958 if (in_probe) {
2947 dev_warn(dev->dev, "Device failed to resume\n"); 2959 nvme_dead_ctrl(dev);
2948 kref_get(&dev->kref);
2949 if (IS_ERR(kthread_run(nvme_remove_dead_ctrl, dev, "nvme%d",
2950 dev->instance))) {
2951 dev_err(dev->dev,
2952 "Failed to start controller remove task\n");
2953 kref_put(&dev->kref, nvme_free_dev);
2954 }
2955 return; 2960 return;
2956 } 2961 }
2957 /* Schedule device resume asynchronously so the reset work is available 2962 /* Schedule device resume asynchronously so the reset work is available
@@ -3086,16 +3091,8 @@ static void nvme_async_probe(struct work_struct *work)
3086{ 3091{
3087 struct nvme_dev *dev = container_of(work, struct nvme_dev, probe_work); 3092 struct nvme_dev *dev = container_of(work, struct nvme_dev, probe_work);
3088 3093
3089 if (nvme_dev_resume(dev)) 3094 if (nvme_dev_resume(dev) && !work_busy(&dev->reset_work))
3090 goto reset; 3095 nvme_dead_ctrl(dev);
3091 return;
3092 reset:
3093 spin_lock(&dev_list_lock);
3094 if (!work_busy(&dev->reset_work)) {
3095 dev->reset_workfn = nvme_reset_failed_dev;
3096 queue_work(nvme_workq, &dev->reset_work);
3097 }
3098 spin_unlock(&dev_list_lock);
3099} 3096}
3100 3097
3101static void nvme_reset_notify(struct pci_dev *pdev, bool prepare) 3098static void nvme_reset_notify(struct pci_dev *pdev, bool prepare)