aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith Busch <keith.busch@intel.com>2014-07-18 13:40:20 -0400
committerJens Axboe <axboe@fb.com>2014-11-04 15:17:08 -0500
commit302c6727e5eb4d0be0e02d077b65feb3e73ea254 (patch)
tree17f37cd779add019ed67a28cb1508e739ff8278a
parentf435c2825b4cc6453b9a1f91418cabbd6ba08cc0 (diff)
NVMe: Fix filesystem sync deadlock on removal
This changes the order of deleting the gendisks so it happens after the nvme IO queues are freed. If a device is removed while a filesystem has associated dirty data, the removal will wait on these to complete before proceeding from del_gendisk, which could have caused deadlock before. The implication of this is that an orderly removal of a responsive device won't necessarily wait for dirty data to be written, but we are not guaranteed the device is even going to respond at this point either. Signed-off-by: Keith Busch <keith.busch@intel.com> Signed-off-by: Matthew Wilcox <matthew.r.wilcox@intel.com> Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r--drivers/block/nvme-core.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c
index d3a025fc1268..48a1be4ab24c 100644
--- a/drivers/block/nvme-core.c
+++ b/drivers/block/nvme-core.c
@@ -2781,8 +2781,8 @@ static void nvme_remove_disks(struct work_struct *ws)
2781{ 2781{
2782 struct nvme_dev *dev = container_of(ws, struct nvme_dev, reset_work); 2782 struct nvme_dev *dev = container_of(ws, struct nvme_dev, reset_work);
2783 2783
2784 nvme_dev_remove(dev);
2785 nvme_free_queues(dev, 1); 2784 nvme_free_queues(dev, 1);
2785 nvme_dev_remove(dev);
2786} 2786}
2787 2787
2788static int nvme_dev_resume(struct nvme_dev *dev) 2788static int nvme_dev_resume(struct nvme_dev *dev)
@@ -2931,9 +2931,9 @@ static void nvme_remove(struct pci_dev *pdev)
2931 flush_work(&dev->reset_work); 2931 flush_work(&dev->reset_work);
2932 flush_work(&dev->cpu_work); 2932 flush_work(&dev->cpu_work);
2933 misc_deregister(&dev->miscdev); 2933 misc_deregister(&dev->miscdev);
2934 nvme_dev_remove(dev);
2935 nvme_dev_shutdown(dev); 2934 nvme_dev_shutdown(dev);
2936 nvme_free_queues(dev, 0); 2935 nvme_free_queues(dev, 0);
2936 nvme_dev_remove(dev);
2937 nvme_release_instance(dev); 2937 nvme_release_instance(dev);
2938 nvme_release_prp_pools(dev); 2938 nvme_release_prp_pools(dev);
2939 kref_put(&dev->kref, nvme_free_dev); 2939 kref_put(&dev->kref, nvme_free_dev);