From: Sagi Grimberg <sagi@xxxxxxxxxxx> 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). Reviewed-by: Hannes Reinecke <hare@xxxxxxx> Tested-by: Sagi Grimberg <sagi@xxxxxxxxxxx> Reviewed-by: Keith Busch <kbusch@xxxxxxxxxx> Cc: Sagi Grimberg <sagi@xxxxxxxxxxx> Cc: Bart Van Assche <bvanassche@xxxxxxx> Cc: Johannes Thumshirn <Johannes.Thumshirn@xxxxxxx> Cc: Chao Leng <lengchao@xxxxxxxxxx> Add code to unquiesce ctrl->connect_q in nvme_stop_queues(), meantime avoid to call blk_mq_quiesce_tagset()/blk_mq_unquiesce_tagset() if this tagset isn't initialized. Signed-off-by: Ming Lei <ming.lei@xxxxxxxxxx> Signed-off-by: Sagi Grimberg <sagi@xxxxxxxxxxx> --- drivers/nvme/host/core.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index c190c56bf702..2dd2d6ff8e7a 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -4623,23 +4623,22 @@ EXPORT_SYMBOL_GPL(nvme_start_freeze); void nvme_stop_queues(struct nvme_ctrl *ctrl) { - struct nvme_ns *ns; + if (list_empty_careful(&ctrl->namespaces)) + return; - down_read(&ctrl->namespaces_rwsem); - list_for_each_entry(ns, &ctrl->namespaces, list) - blk_mq_quiesce_queue(ns->queue); - up_read(&ctrl->namespaces_rwsem); + blk_mq_quiesce_tagset(ctrl->tagset); + + if (ctrl->connect_q) + blk_mq_unquiesce_queue(ctrl->connect_q); } EXPORT_SYMBOL_GPL(nvme_stop_queues); void nvme_start_queues(struct nvme_ctrl *ctrl) { - struct nvme_ns *ns; + if (list_empty_careful(&ctrl->namespaces)) + return; - down_read(&ctrl->namespaces_rwsem); - list_for_each_entry(ns, &ctrl->namespaces, list) - blk_mq_unquiesce_queue(ns->queue); - up_read(&ctrl->namespaces_rwsem); + blk_mq_unquiesce_tagset(ctrl->tagset); } EXPORT_SYMBOL_GPL(nvme_start_queues); -- 2.25.2