]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
nvme: split nvme_uninit_ctrl into stop and uninit
authorSagi Grimberg <sagi@grimberg.me>
Sun, 2 Jul 2017 07:56:43 +0000 (10:56 +0300)
committerSagi Grimberg <sagi@grimberg.me>
Thu, 6 Jul 2017 06:49:42 +0000 (09:49 +0300)
Usually before we teardown the controller we want to:
1. complete/cancel any ctrl inflight works
2. remove ctrl namespaces (only for removal though, resets
   shouldn't remove any namespaces).

but we do not want to destroy the controller device as
we might use it for logging during the teardown stage.

This patch adds nvme_start_ctrl() which queues inflight
controller works (aen, ns scan, queue start and keep-alive
if kato is set) and nvme_stop_ctrl() which cancels the works
namespace removal is left to the callers to handle.

Move nvme_uninit_ctrl after we are done with the
controller device.

Reviewed-by: Keith Busch <keith.busch@intel.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
drivers/nvme/host/core.c
drivers/nvme/host/fc.c
drivers/nvme/host/nvme.h
drivers/nvme/host/pci.c
drivers/nvme/host/rdma.c
drivers/nvme/target/loop.c

index 48cafaa6fbc50b50a82d25234bf3115f9d10726a..cb96f4a7ae3a93b4f6736d6b375098a88e935fa3 100644 (file)
@@ -2591,12 +2591,29 @@ static void nvme_release_instance(struct nvme_ctrl *ctrl)
        spin_unlock(&dev_list_lock);
 }
 
-void nvme_uninit_ctrl(struct nvme_ctrl *ctrl)
+void nvme_stop_ctrl(struct nvme_ctrl *ctrl)
 {
+       nvme_stop_keep_alive(ctrl);
        flush_work(&ctrl->async_event_work);
        flush_work(&ctrl->scan_work);
-       nvme_remove_namespaces(ctrl);
+}
+EXPORT_SYMBOL_GPL(nvme_stop_ctrl);
+
+void nvme_start_ctrl(struct nvme_ctrl *ctrl)
+{
+       if (ctrl->kato)
+               nvme_start_keep_alive(ctrl);
+
+       if (ctrl->queue_count > 1) {
+               nvme_queue_scan(ctrl);
+               nvme_queue_async_events(ctrl);
+               nvme_start_queues(ctrl);
+       }
+}
+EXPORT_SYMBOL_GPL(nvme_start_ctrl);
 
+void nvme_uninit_ctrl(struct nvme_ctrl *ctrl)
+{
        device_destroy(nvme_class, MKDEV(nvme_char_major, ctrl->instance));
 
        spin_lock(&dev_list_lock);
index 8d55e78279322bc10bc48d0a6758aace1e17ec05..d666ada39a9be6d6f27fff36904af75063c035d6 100644 (file)
@@ -2232,7 +2232,6 @@ nvme_fc_create_io_queues(struct nvme_fc_ctrl *ctrl)
 out_delete_hw_queues:
        nvme_fc_delete_hw_io_queues(ctrl);
 out_cleanup_blk_queue:
-       nvme_stop_keep_alive(&ctrl->ctrl);
        blk_cleanup_queue(ctrl->ctrl.connect_q);
 out_free_tag_set:
        blk_mq_free_tag_set(&ctrl->tag_set);
@@ -2366,8 +2365,6 @@ nvme_fc_create_association(struct nvme_fc_ctrl *ctrl)
                goto out_disconnect_admin_queue;
        }
 
-       nvme_start_keep_alive(&ctrl->ctrl);
-
        /* FC-NVME supports normal SGL Data Block Descriptors */
 
        if (opts->queue_size > ctrl->ctrl.maxcmd) {
@@ -2401,17 +2398,12 @@ nvme_fc_create_association(struct nvme_fc_ctrl *ctrl)
 
        ctrl->ctrl.nr_reconnects = 0;
 
-       if (ctrl->ctrl.queue_count > 1) {
-               nvme_start_queues(&ctrl->ctrl);
-               nvme_queue_scan(&ctrl->ctrl);
-               nvme_queue_async_events(&ctrl->ctrl);
-       }
+       nvme_start_ctrl(&ctrl->ctrl);
 
        return 0;       /* Success */
 
 out_term_aen_ops:
        nvme_fc_term_aen_ops(ctrl);
-       nvme_stop_keep_alive(&ctrl->ctrl);
 out_disconnect_admin_queue:
        /* send a Disconnect(association) LS to fc-nvme target */
        nvme_fc_xmt_disconnect_assoc(ctrl);
@@ -2434,8 +2426,6 @@ nvme_fc_delete_association(struct nvme_fc_ctrl *ctrl)
 {
        unsigned long flags;
 
-       nvme_stop_keep_alive(&ctrl->ctrl);
-
        spin_lock_irqsave(&ctrl->lock, flags);
        ctrl->flags |= FCCTRL_TERMIO;
        ctrl->iocnt = 0;
@@ -2517,7 +2507,8 @@ nvme_fc_delete_ctrl_work(struct work_struct *work)
 
        cancel_work_sync(&ctrl->ctrl.reset_work);
        cancel_delayed_work_sync(&ctrl->connect_work);
-
+       nvme_stop_ctrl(&ctrl->ctrl);
+       nvme_remove_namespaces(&ctrl->ctrl);
        /*
         * kill the association on the link side.  this will block
         * waiting for io to terminate
@@ -2612,6 +2603,7 @@ nvme_fc_reset_ctrl_work(struct work_struct *work)
                container_of(work, struct nvme_fc_ctrl, ctrl.reset_work);
        int ret;
 
+       nvme_stop_ctrl(&ctrl->ctrl);
        /* will block will waiting for io to terminate */
        nvme_fc_delete_association(ctrl);
 
index e0b83311d5debd2374d6f03ac6b6945e0be46833..8f2a168ddc013d8bc1a10685e611fdc309429b6f 100644 (file)
@@ -280,6 +280,8 @@ int nvme_shutdown_ctrl(struct nvme_ctrl *ctrl);
 int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev,
                const struct nvme_ctrl_ops *ops, unsigned long quirks);
 void nvme_uninit_ctrl(struct nvme_ctrl *ctrl);
+void nvme_start_ctrl(struct nvme_ctrl *ctrl);
+void nvme_stop_ctrl(struct nvme_ctrl *ctrl);
 void nvme_put_ctrl(struct nvme_ctrl *ctrl);
 int nvme_init_identify(struct nvme_ctrl *ctrl);
 
index d9c0010a9bbcb22257f50d9e1e2c105f9fe33173..882ed36771176e16b4a6b7f435ae930d3726abfc 100644 (file)
@@ -2134,15 +2134,6 @@ static void nvme_reset_work(struct work_struct *work)
        if (result)
                goto out;
 
-       /*
-        * A controller that can not execute IO typically requires user
-        * intervention to correct. For such degraded controllers, the driver
-        * should not submit commands the user did not request, so skip
-        * registering for asynchronous event notification on this condition.
-        */
-       if (dev->online_queues > 1)
-               nvme_queue_async_events(&dev->ctrl);
-
        /*
         * Keep the controller around but remove all namespaces if we don't have
         * any working I/O queue.
@@ -2163,8 +2154,7 @@ static void nvme_reset_work(struct work_struct *work)
                goto out;
        }
 
-       if (dev->online_queues > 1)
-               nvme_queue_scan(&dev->ctrl);
+       nvme_start_ctrl(&dev->ctrl);
        return;
 
  out:
@@ -2341,11 +2331,13 @@ static void nvme_remove(struct pci_dev *pdev)
        }
 
        flush_work(&dev->ctrl.reset_work);
-       nvme_uninit_ctrl(&dev->ctrl);
+       nvme_stop_ctrl(&dev->ctrl);
+       nvme_remove_namespaces(&dev->ctrl);
        nvme_dev_disable(dev, true);
        nvme_free_host_mem(dev);
        nvme_dev_remove_admin(dev);
        nvme_free_queues(dev, 0);
+       nvme_uninit_ctrl(&dev->ctrl);
        nvme_release_prp_pools(dev);
        nvme_dev_unmap(dev);
        nvme_put_ctrl(&dev->ctrl);
index 6f8f9ffcbc005f4bd148f3a39d47c7acb6988812..ccdbd99d5a1c89a1041083f90d44c826f1965732 100644 (file)
@@ -732,8 +732,6 @@ static void nvme_rdma_reconnect_ctrl_work(struct work_struct *work)
        if (ret)
                goto requeue;
 
-       nvme_start_keep_alive(&ctrl->ctrl);
-
        if (ctrl->ctrl.queue_count > 1) {
                ret = nvme_rdma_init_io_queues(ctrl);
                if (ret)
@@ -751,10 +749,7 @@ static void nvme_rdma_reconnect_ctrl_work(struct work_struct *work)
        WARN_ON_ONCE(!changed);
        ctrl->ctrl.nr_reconnects = 0;
 
-       if (ctrl->ctrl.queue_count > 1) {
-               nvme_queue_scan(&ctrl->ctrl);
-               nvme_queue_async_events(&ctrl->ctrl);
-       }
+       nvme_start_ctrl(&ctrl->ctrl);
 
        dev_info(ctrl->ctrl.device, "Successfully reconnected\n");
 
@@ -772,7 +767,7 @@ static void nvme_rdma_error_recovery_work(struct work_struct *work)
                        struct nvme_rdma_ctrl, err_work);
        int i;
 
-       nvme_stop_keep_alive(&ctrl->ctrl);
+       nvme_stop_ctrl(&ctrl->ctrl);
 
        for (i = 0; i < ctrl->ctrl.queue_count; i++)
                clear_bit(NVME_RDMA_Q_LIVE, &ctrl->queues[i].flags);
@@ -1603,8 +1598,6 @@ static int nvme_rdma_configure_admin_queue(struct nvme_rdma_ctrl *ctrl)
        if (error)
                goto out_cleanup_queue;
 
-       nvme_start_keep_alive(&ctrl->ctrl);
-
        return 0;
 
 out_cleanup_queue:
@@ -1622,7 +1615,6 @@ out_free_queue:
 
 static void nvme_rdma_shutdown_ctrl(struct nvme_rdma_ctrl *ctrl)
 {
-       nvme_stop_keep_alive(&ctrl->ctrl);
        cancel_work_sync(&ctrl->err_work);
        cancel_delayed_work_sync(&ctrl->reconnect_work);
 
@@ -1645,10 +1637,12 @@ static void nvme_rdma_shutdown_ctrl(struct nvme_rdma_ctrl *ctrl)
 
 static void __nvme_rdma_remove_ctrl(struct nvme_rdma_ctrl *ctrl, bool shutdown)
 {
-       nvme_uninit_ctrl(&ctrl->ctrl);
+       nvme_stop_ctrl(&ctrl->ctrl);
+       nvme_remove_namespaces(&ctrl->ctrl);
        if (shutdown)
                nvme_rdma_shutdown_ctrl(ctrl);
 
+       nvme_uninit_ctrl(&ctrl->ctrl);
        if (ctrl->ctrl.tagset) {
                blk_cleanup_queue(ctrl->ctrl.connect_q);
                blk_mq_free_tag_set(&ctrl->tag_set);
@@ -1710,6 +1704,7 @@ static void nvme_rdma_reset_ctrl_work(struct work_struct *work)
        int ret;
        bool changed;
 
+       nvme_stop_ctrl(&ctrl->ctrl);
        nvme_rdma_shutdown_ctrl(ctrl);
 
        ret = nvme_rdma_configure_admin_queue(ctrl);
@@ -1739,11 +1734,7 @@ static void nvme_rdma_reset_ctrl_work(struct work_struct *work)
        changed = nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_LIVE);
        WARN_ON_ONCE(!changed);
 
-       if (ctrl->ctrl.queue_count > 1) {
-               nvme_start_queues(&ctrl->ctrl);
-               nvme_queue_scan(&ctrl->ctrl);
-               nvme_queue_async_events(&ctrl->ctrl);
-       }
+       nvme_start_ctrl(&ctrl->ctrl);
 
        return;
 
@@ -1931,15 +1922,11 @@ static struct nvme_ctrl *nvme_rdma_create_ctrl(struct device *dev,
        list_add_tail(&ctrl->list, &nvme_rdma_ctrl_list);
        mutex_unlock(&nvme_rdma_ctrl_mutex);
 
-       if (ctrl->ctrl.queue_count > 1) {
-               nvme_queue_scan(&ctrl->ctrl);
-               nvme_queue_async_events(&ctrl->ctrl);
-       }
+       nvme_start_ctrl(&ctrl->ctrl);
 
        return &ctrl->ctrl;
 
 out_remove_admin_queue:
-       nvme_stop_keep_alive(&ctrl->ctrl);
        nvme_rdma_destroy_admin_queue(ctrl);
 out_kfree_queues:
        kfree(ctrl->queues);
index 6a0b70685e7742fdb080cc1850849b07daaa0f74..717ed7ddb2f6d59fdd79d5e21565184f3acdf5ec 100644 (file)
@@ -407,8 +407,6 @@ static int nvme_loop_configure_admin_queue(struct nvme_loop_ctrl *ctrl)
        if (error)
                goto out_cleanup_queue;
 
-       nvme_start_keep_alive(&ctrl->ctrl);
-
        return 0;
 
 out_cleanup_queue:
@@ -422,8 +420,6 @@ out_free_sq:
 
 static void nvme_loop_shutdown_ctrl(struct nvme_loop_ctrl *ctrl)
 {
-       nvme_stop_keep_alive(&ctrl->ctrl);
-
        if (ctrl->ctrl.queue_count > 1) {
                nvme_stop_queues(&ctrl->ctrl);
                blk_mq_tagset_busy_iter(&ctrl->tag_set,
@@ -446,8 +442,10 @@ static void nvme_loop_del_ctrl_work(struct work_struct *work)
        struct nvme_loop_ctrl *ctrl = container_of(work,
                                struct nvme_loop_ctrl, delete_work);
 
-       nvme_uninit_ctrl(&ctrl->ctrl);
+       nvme_stop_ctrl(&ctrl->ctrl);
+       nvme_remove_namespaces(&ctrl->ctrl);
        nvme_loop_shutdown_ctrl(ctrl);
+       nvme_uninit_ctrl(&ctrl->ctrl);
        nvme_put_ctrl(&ctrl->ctrl);
 }
 
@@ -495,6 +493,7 @@ static void nvme_loop_reset_ctrl_work(struct work_struct *work)
        bool changed;
        int ret;
 
+       nvme_stop_ctrl(&ctrl->ctrl);
        nvme_loop_shutdown_ctrl(ctrl);
 
        ret = nvme_loop_configure_admin_queue(ctrl);
@@ -515,10 +514,7 @@ static void nvme_loop_reset_ctrl_work(struct work_struct *work)
        changed = nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_LIVE);
        WARN_ON_ONCE(!changed);
 
-       nvme_queue_scan(&ctrl->ctrl);
-       nvme_queue_async_events(&ctrl->ctrl);
-
-       nvme_start_queues(&ctrl->ctrl);
+       nvme_start_ctrl(&ctrl->ctrl);
 
        return;
 
@@ -653,10 +649,7 @@ static struct nvme_ctrl *nvme_loop_create_ctrl(struct device *dev,
        list_add_tail(&ctrl->list, &nvme_loop_ctrl_list);
        mutex_unlock(&nvme_loop_ctrl_mutex);
 
-       if (opts->nr_io_queues) {
-               nvme_queue_scan(&ctrl->ctrl);
-               nvme_queue_async_events(&ctrl->ctrl);
-       }
+       nvme_start_ctrl(&ctrl->ctrl);
 
        return &ctrl->ctrl;