summaryrefslogtreecommitdiff
path: root/drivers/nvme
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2016-01-06 20:58:13 +0100
committerTakashi Iwai <tiwai@suse.de>2016-01-06 21:14:35 +0100
commit9d9938854efcf2f21381b930bc1324e95640e0c4 (patch)
tree7b136c25af5fcc64258f3427f985c1dc667ae0bd /drivers/nvme
parentca9ea7a5ffda53ce9e9f3e14b9b104d85db47c7d (diff)
parent3f37b26f8d57756b591383a9d8ce1cd628bc773c (diff)
Merge branch 'for-linus' into for-next
Conflicts: drivers/gpu/drm/i915/intel_display.c sound/soc/intel/skylake/skl.h
Diffstat (limited to 'drivers/nvme')
-rw-r--r--drivers/nvme/host/pci.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 9e294ff4e652..0c67b57be83c 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -2540,8 +2540,17 @@ static void nvme_ns_remove(struct nvme_ns *ns)
{
bool kill = nvme_io_incapable(ns->dev) && !blk_queue_dying(ns->queue);
- if (kill)
+ if (kill) {
blk_set_queue_dying(ns->queue);
+
+ /*
+ * The controller was shutdown first if we got here through
+ * device removal. The shutdown may requeue outstanding
+ * requests. These need to be aborted immediately so
+ * del_gendisk doesn't block indefinitely for their completion.
+ */
+ blk_mq_abort_requeue_list(ns->queue);
+ }
if (ns->disk->flags & GENHD_FL_UP)
del_gendisk(ns->disk);
if (kill || !blk_queue_dying(ns->queue)) {
@@ -2977,6 +2986,15 @@ static void nvme_dev_remove(struct nvme_dev *dev)
{
struct nvme_ns *ns, *next;
+ if (nvme_io_incapable(dev)) {
+ /*
+ * If the device is not capable of IO (surprise hot-removal,
+ * for example), we need to quiesce prior to deleting the
+ * namespaces. This will end outstanding requests and prevent
+ * attempts to sync dirty data.
+ */
+ nvme_dev_shutdown(dev);
+ }
list_for_each_entry_safe(ns, next, &dev->namespaces, list)
nvme_ns_remove(ns);
}