nvme: use blk_mq_[un]quiesce_tagset
authorChao Leng <lengchao@huawei.com>
Tue, 1 Nov 2022 15:00:50 +0000 (16:00 +0100)
committerJens Axboe <axboe@kernel.dk>
Wed, 2 Nov 2022 14:35:34 +0000 (08:35 -0600)
All controller namespaces share the same tagset, so we can use this
interface which does the optimal operation for parallel quiesce based on
the tagset type(e.g. blocking tagsets and non-blocking tagsets).

nvme connect_q should not be quiesced when quiesce tagset, so set the
QUEUE_FLAG_SKIP_TAGSET_QUIESCE to skip it when init connect_q.

Currently we use NVME_NS_STOPPED to ensure pairing quiescing and
unquiescing. If use blk_mq_[un]quiesce_tagset, NVME_NS_STOPPED will be
invalided, so introduce NVME_CTRL_STOPPED to replace NVME_NS_STOPPED.
In addition, we never really quiesce a single namespace. It is a better
choice to move the flag from ns to ctrl.

Signed-off-by: Chao Leng <lengchao@huawei.com>
[hch: rebased on top of prep patches]
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Keith Busch <kbusch@kernel.org>
Reviewed-by: Chao Leng <lengchao@huawei.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
Link: https://lore.kernel.org/r/20221101150050.3510-15-hch@lst.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/nvme/host/core.c
drivers/nvme/host/nvme.h

index 66b0b6e..f94b05c 100644 (file)
@@ -4895,6 +4895,8 @@ int nvme_alloc_io_tag_set(struct nvme_ctrl *ctrl, struct blk_mq_tag_set *set,
                        ret = PTR_ERR(ctrl->connect_q);
                        goto out_free_tag_set;
                }
+               blk_queue_flag_set(QUEUE_FLAG_SKIP_TAGSET_QUIESCE,
+                                  ctrl->connect_q);
        }
 
        ctrl->tagset = set;
@@ -5096,20 +5098,6 @@ out:
 }
 EXPORT_SYMBOL_GPL(nvme_init_ctrl);
 
-static void nvme_start_ns_queue(struct nvme_ns *ns)
-{
-       if (test_and_clear_bit(NVME_NS_STOPPED, &ns->flags))
-               blk_mq_unquiesce_queue(ns->queue);
-}
-
-static void nvme_stop_ns_queue(struct nvme_ns *ns)
-{
-       if (!test_and_set_bit(NVME_NS_STOPPED, &ns->flags))
-               blk_mq_quiesce_queue(ns->queue);
-       else
-               blk_mq_wait_quiesce_done(ns->queue->tag_set);
-}
-
 /* let I/O to all namespaces fail in preparation for surprise removal */
 void nvme_mark_namespaces_dead(struct nvme_ctrl *ctrl)
 {
@@ -5172,23 +5160,17 @@ EXPORT_SYMBOL_GPL(nvme_start_freeze);
 
 void nvme_stop_queues(struct nvme_ctrl *ctrl)
 {
-       struct nvme_ns *ns;
-
-       down_read(&ctrl->namespaces_rwsem);
-       list_for_each_entry(ns, &ctrl->namespaces, list)
-               nvme_stop_ns_queue(ns);
-       up_read(&ctrl->namespaces_rwsem);
+       if (!test_and_set_bit(NVME_CTRL_STOPPED, &ctrl->flags))
+               blk_mq_quiesce_tagset(ctrl->tagset);
+       else
+               blk_mq_wait_quiesce_done(ctrl->tagset);
 }
 EXPORT_SYMBOL_GPL(nvme_stop_queues);
 
 void nvme_start_queues(struct nvme_ctrl *ctrl)
 {
-       struct nvme_ns *ns;
-
-       down_read(&ctrl->namespaces_rwsem);
-       list_for_each_entry(ns, &ctrl->namespaces, list)
-               nvme_start_ns_queue(ns);
-       up_read(&ctrl->namespaces_rwsem);
+       if (test_and_clear_bit(NVME_CTRL_STOPPED, &ctrl->flags))
+               blk_mq_unquiesce_tagset(ctrl->tagset);
 }
 EXPORT_SYMBOL_GPL(nvme_start_queues);
 
index 1cd7168..f9df106 100644 (file)
@@ -237,6 +237,7 @@ enum nvme_ctrl_flags {
        NVME_CTRL_FAILFAST_EXPIRED      = 0,
        NVME_CTRL_ADMIN_Q_STOPPED       = 1,
        NVME_CTRL_STARTED_ONCE          = 2,
+       NVME_CTRL_STOPPED               = 3,
 };
 
 struct nvme_ctrl {
@@ -486,7 +487,6 @@ struct nvme_ns {
 #define NVME_NS_ANA_PENDING    2
 #define NVME_NS_FORCE_RO       3
 #define NVME_NS_READY          4
-#define NVME_NS_STOPPED                5
 
        struct cdev             cdev;
        struct device           cdev_device;