nvme: don't call revalidate_disk from nvme_set_queue_dying
authorChristoph Hellwig <hch@lst.de>
Sun, 23 Aug 2020 09:10:43 +0000 (11:10 +0200)
committerJens Axboe <axboe@kernel.dk>
Tue, 1 Sep 2020 22:49:25 +0000 (16:49 -0600)
In nvme_set_queue_dying we really just want to ensure the disk and bdev
sizes are set to zero.  Going through revalidate_disk leads to a somewhat
arcance and complex callchain relying on special behavior in a few
places.  Instead just lift the set_capacity directly to
nvme_set_queue_dying, and rename and move the nvme_mpath_update_disk_size
helper so that we can use it in nvme_set_queue_dying to propagate the
size to the bdev without detours.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/nvme/host/core.c
drivers/nvme/host/nvme.h

index d543bc1..c7e01d9 100644 (file)
@@ -94,21 +94,34 @@ static void nvme_put_subsystem(struct nvme_subsystem *subsys);
 static void nvme_remove_invalid_namespaces(struct nvme_ctrl *ctrl,
                                           unsigned nsid);
 
+static void nvme_update_bdev_size(struct gendisk *disk)
+{
+       struct block_device *bdev = bdget_disk(disk, 0);
+
+       if (bdev) {
+               bd_set_nr_sectors(bdev, get_capacity(disk));
+               bdput(bdev);
+       }
+}
+
+/*
+ * Prepare a queue for teardown.
+ *
+ * This must forcibly unquiesce queues to avoid blocking dispatch, and only set
+ * the capacity to 0 after that to avoid blocking dispatchers that may be
+ * holding bd_butex.  This will end buffered writers dirtying pages that can't
+ * be synced.
+ */
 static void nvme_set_queue_dying(struct nvme_ns *ns)
 {
-       /*
-        * Revalidating a dead namespace sets capacity to 0. This will end
-        * buffered writers dirtying pages that can't be synced.
-        */
        if (test_and_set_bit(NVME_NS_DEAD, &ns->flags))
                return;
+
        blk_set_queue_dying(ns->queue);
-       /* Forcibly unquiesce queues to avoid blocking dispatch */
        blk_mq_unquiesce_queue(ns->queue);
-       /*
-        * Revalidate after unblocking dispatchers that may be holding bd_butex
-        */
-       revalidate_disk(ns->disk);
+
+       set_capacity(ns->disk, 0);
+       nvme_update_bdev_size(ns->disk);
 }
 
 static void nvme_queue_scan(struct nvme_ctrl *ctrl)
@@ -2134,7 +2147,7 @@ static int __nvme_revalidate_disk(struct gendisk *disk, struct nvme_id_ns *id)
                nvme_update_disk_info(ns->head->disk, ns, id);
                blk_stack_limits(&ns->head->disk->queue->limits,
                                 &ns->queue->limits, 0);
-               nvme_mpath_update_disk_size(ns->head->disk);
+               nvme_update_bdev_size(ns->head->disk);
        }
 #endif
        return 0;
index aab130f..87737fa 100644 (file)
@@ -683,16 +683,6 @@ static inline void nvme_trace_bio_complete(struct request *req,
                trace_block_bio_complete(ns->head->disk->queue, req->bio);
 }
 
-static inline void nvme_mpath_update_disk_size(struct gendisk *disk)
-{
-       struct block_device *bdev = bdget_disk(disk, 0);
-
-       if (bdev) {
-               bd_set_nr_sectors(bdev, get_capacity(disk));
-               bdput(bdev);
-       }
-}
-
 extern struct device_attribute dev_attr_ana_grpid;
 extern struct device_attribute dev_attr_ana_state;
 extern struct device_attribute subsys_attr_iopolicy;
@@ -767,9 +757,6 @@ static inline void nvme_mpath_wait_freeze(struct nvme_subsystem *subsys)
 static inline void nvme_mpath_start_freeze(struct nvme_subsystem *subsys)
 {
 }
-static inline void nvme_mpath_update_disk_size(struct gendisk *disk)
-{
-}
 #endif /* CONFIG_NVME_MULTIPATH */
 
 #ifdef CONFIG_BLK_DEV_ZONED