return 1;
 }
 
-static void nvme_pci_update_nr_queues(struct nvme_dev *dev)
+static bool nvme_pci_update_nr_queues(struct nvme_dev *dev)
 {
        if (!dev->ctrl.tagset) {
                nvme_alloc_io_tag_set(&dev->ctrl, &dev->tagset, &nvme_mq_ops,
                                nvme_pci_nr_maps(dev), sizeof(struct nvme_iod));
-               return;
+               return true;
+       }
+
+       /* Give up if we are racing with nvme_dev_disable() */
+       if (!mutex_trylock(&dev->shutdown_lock))
+               return false;
+
+       /* Check if nvme_dev_disable() has been executed already */
+       if (!dev->online_queues) {
+               mutex_unlock(&dev->shutdown_lock);
+               return false;
        }
 
        blk_mq_update_nr_hw_queues(&dev->tagset, dev->online_queues - 1);
        /* free previously allocated queues that are no longer usable */
        nvme_free_queues(dev, dev->online_queues);
+       mutex_unlock(&dev->shutdown_lock);
+       return true;
 }
 
 static int nvme_pci_enable(struct nvme_dev *dev)
                nvme_dbbuf_set(dev);
                nvme_unquiesce_io_queues(&dev->ctrl);
                nvme_wait_freeze(&dev->ctrl);
-               nvme_pci_update_nr_queues(dev);
+               if (!nvme_pci_update_nr_queues(dev))
+                       goto out;
                nvme_unfreeze(&dev->ctrl);
        } else {
                dev_warn(dev->ctrl.device, "IO queues lost\n");