diff options
author | Keith Busch <keith.busch@intel.com> | 2014-07-18 11:40:20 -0600 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2014-11-04 13:17:08 -0700 |
commit | 302c6727e5eb4d0be0e02d077b65feb3e73ea254 (patch) | |
tree | 17f37cd779add019ed67a28cb1508e739ff8278a /drivers/block | |
parent | f435c2825b4cc6453b9a1f91418cabbd6ba08cc0 (diff) | |
download | linux-302c6727e5eb4d0be0e02d077b65feb3e73ea254.tar.gz linux-302c6727e5eb4d0be0e02d077b65feb3e73ea254.tar.bz2 linux-302c6727e5eb4d0be0e02d077b65feb3e73ea254.zip |
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>
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/nvme-core.c | 4 |
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) { struct nvme_dev *dev = container_of(ws, struct nvme_dev, reset_work); - nvme_dev_remove(dev); nvme_free_queues(dev, 1); + nvme_dev_remove(dev); } static int nvme_dev_resume(struct nvme_dev *dev) @@ -2931,9 +2931,9 @@ static void nvme_remove(struct pci_dev *pdev) flush_work(&dev->reset_work); flush_work(&dev->cpu_work); misc_deregister(&dev->miscdev); - nvme_dev_remove(dev); nvme_dev_shutdown(dev); nvme_free_queues(dev, 0); + nvme_dev_remove(dev); nvme_release_instance(dev); nvme_release_prp_pools(dev); kref_put(&dev->kref, nvme_free_dev); |