nvme-pci: refactor the tagset handling in nvme_reset_work
authorChristoph Hellwig <hch@lst.de>
Tue, 1 Nov 2022 15:00:38 +0000 (16:00 +0100)
committerJens Axboe <axboe@kernel.dk>
Wed, 2 Nov 2022 14:35:19 +0000 (08:35 -0600)
The code to create, update or delete a tagset and namespaces in
nvme_reset_work is a bit convoluted.  Refactor it with a two high-level
conditionals for first probe vs reset and I/O queues vs no I/O queues
to make the code flow more clear.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
Link: https://lore.kernel.org/r/20221101150050.3510-3-hch@lst.de
[axboe: fix whitespace issue]
Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/nvme/host/pci.c

index 5f1d71a..6ab7be0 100644 (file)
@@ -2898,24 +2898,36 @@ static void nvme_reset_work(struct work_struct *work)
        if (result)
                goto out;
 
-       /*
-        * Keep the controller around but remove all namespaces if we don't have
-        * any working I/O queue.
-        */
-       if (dev->online_queues < 2) {
-               dev_warn(dev->ctrl.device, "IO queues not created\n");
-               nvme_kill_queues(&dev->ctrl);
-               nvme_remove_namespaces(&dev->ctrl);
-               nvme_free_tagset(dev);
+       if (dev->ctrl.tagset) {
+               /*
+                * This is a controller reset and we already have a tagset.
+                * Freeze and update the number of I/O queues as thos might have
+                * changed.  If there are no I/O queues left after this reset,
+                * keep the controller around but remove all namespaces.
+                */
+               if (dev->online_queues > 1) {
+                       nvme_start_queues(&dev->ctrl);
+                       nvme_wait_freeze(&dev->ctrl);
+                       nvme_pci_update_nr_queues(dev);
+                       nvme_dbbuf_set(dev);
+                       nvme_unfreeze(&dev->ctrl);
+               } else {
+                       dev_warn(dev->ctrl.device, "IO queues lost\n");
+                       nvme_kill_queues(&dev->ctrl);
+                       nvme_remove_namespaces(&dev->ctrl);
+                       nvme_free_tagset(dev);
+               }
        } else {
-               nvme_start_queues(&dev->ctrl);
-               nvme_wait_freeze(&dev->ctrl);
-               if (!dev->ctrl.tagset)
+               /*
+                * First probe.  Still allow the controller to show up even if
+                * there are no namespaces.
+                */
+               if (dev->online_queues > 1) {
                        nvme_pci_alloc_tag_set(dev);
-               else
-                       nvme_pci_update_nr_queues(dev);
-               nvme_dbbuf_set(dev);
-               nvme_unfreeze(&dev->ctrl);
+                       nvme_dbbuf_set(dev);
+               } else {
+                       dev_warn(dev->ctrl.device, "IO queues not created\n");
+               }
        }
 
        /*