aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorKeith Busch <keith.busch@intel.com>2015-12-11 15:14:28 -0500
committerJens Axboe <axboe@fb.com>2015-12-22 12:12:04 -0500
commitb5875222de2fb91339db79a753677ba4f68120d0 (patch)
tree458e729691435b753d23e860f7e76d6e0fbdf922 /drivers
parentaf096e2235c5de76af7e8749f59a90de07f5e943 (diff)
NVMe: IO ending fixes on surprise removal
This patch fixes a lost request discovered during IO + hot removal. The driver's pci removal deletes gendisks prior to shutting down the controller to allow dirty data to sync. Dirty data can not be synced on a surprise removal, though, and would potentially block indefinitely. The driver previously had marked the queue as dying in this scenario to prevent new requests from attempting, however it will still block for requests that already entered the queue. This patch fixes this by quiescing IO first, then aborting the requeued requests before deleting disks. Reported-by: Sujith Pandel <sujith_pandel@dell.com> Signed-off-by: Keith Busch <keith.busch@intel.com> Tested-by: Sujith Pandel <sujith_pandel@dell.com> Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'drivers')
-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)
2540{ 2540{
2541 bool kill = nvme_io_incapable(ns->dev) && !blk_queue_dying(ns->queue); 2541 bool kill = nvme_io_incapable(ns->dev) && !blk_queue_dying(ns->queue);
2542 2542
2543 if (kill) 2543 if (kill) {
2544 blk_set_queue_dying(ns->queue); 2544 blk_set_queue_dying(ns->queue);
2545
2546 /*
2547 * The controller was shutdown first if we got here through
2548 * device removal. The shutdown may requeue outstanding
2549 * requests. These need to be aborted immediately so
2550 * del_gendisk doesn't block indefinitely for their completion.
2551 */
2552 blk_mq_abort_requeue_list(ns->queue);
2553 }
2545 if (ns->disk->flags & GENHD_FL_UP) 2554 if (ns->disk->flags & GENHD_FL_UP)
2546 del_gendisk(ns->disk); 2555 del_gendisk(ns->disk);
2547 if (kill || !blk_queue_dying(ns->queue)) { 2556 if (kill || !blk_queue_dying(ns->queue)) {
@@ -2977,6 +2986,15 @@ static void nvme_dev_remove(struct nvme_dev *dev)
2977{ 2986{
2978 struct nvme_ns *ns, *next; 2987 struct nvme_ns *ns, *next;
2979 2988
2989 if (nvme_io_incapable(dev)) {
2990 /*
2991 * If the device is not capable of IO (surprise hot-removal,
2992 * for example), we need to quiesce prior to deleting the
2993 * namespaces. This will end outstanding requests and prevent
2994 * attempts to sync dirty data.
2995 */
2996 nvme_dev_shutdown(dev);
2997 }
2980 list_for_each_entry_safe(ns, next, &dev->namespaces, list) 2998 list_for_each_entry_safe(ns, next, &dev->namespaces, list)
2981 nvme_ns_remove(ns); 2999 nvme_ns_remove(ns);
2982} 3000}