|
@@ -2035,13 +2035,12 @@ static void nvme_disable_io_queues(struct nvme_dev *dev, int queues)
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
- * Return: error value if an error occurred setting up the queues or calling
|
|
|
- * Identify Device. 0 if these succeeded, even if adding some of the
|
|
|
- * namespaces failed. At the moment, these failures are silent. TBD which
|
|
|
- * failures should be reported.
|
|
|
+ * return error value only when tagset allocation failed
|
|
|
*/
|
|
|
static int nvme_dev_add(struct nvme_dev *dev)
|
|
|
{
|
|
|
+ int ret;
|
|
|
+
|
|
|
if (!dev->ctrl.tagset) {
|
|
|
dev->tagset.ops = &nvme_mq_ops;
|
|
|
dev->tagset.nr_hw_queues = dev->online_queues - 1;
|
|
@@ -2057,8 +2056,12 @@ static int nvme_dev_add(struct nvme_dev *dev)
|
|
|
dev->tagset.flags = BLK_MQ_F_SHOULD_MERGE;
|
|
|
dev->tagset.driver_data = dev;
|
|
|
|
|
|
- if (blk_mq_alloc_tag_set(&dev->tagset))
|
|
|
- return 0;
|
|
|
+ ret = blk_mq_alloc_tag_set(&dev->tagset);
|
|
|
+ if (ret) {
|
|
|
+ dev_warn(dev->ctrl.device,
|
|
|
+ "IO queues tagset allocation failed %d\n", ret);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
dev->ctrl.tagset = &dev->tagset;
|
|
|
|
|
|
nvme_dbbuf_set(dev);
|
|
@@ -2291,6 +2294,7 @@ static void nvme_reset_work(struct work_struct *work)
|
|
|
container_of(work, struct nvme_dev, ctrl.reset_work);
|
|
|
bool was_suspend = !!(dev->ctrl.ctrl_config & NVME_CC_SHN_NORMAL);
|
|
|
int result = -ENODEV;
|
|
|
+ enum nvme_ctrl_state new_state = NVME_CTRL_LIVE;
|
|
|
|
|
|
if (WARN_ON(dev->ctrl.state != NVME_CTRL_RESETTING))
|
|
|
goto out;
|
|
@@ -2354,15 +2358,23 @@ static void nvme_reset_work(struct work_struct *work)
|
|
|
dev_warn(dev->ctrl.device, "IO queues not created\n");
|
|
|
nvme_kill_queues(&dev->ctrl);
|
|
|
nvme_remove_namespaces(&dev->ctrl);
|
|
|
+ new_state = NVME_CTRL_ADMIN_ONLY;
|
|
|
} else {
|
|
|
nvme_start_queues(&dev->ctrl);
|
|
|
nvme_wait_freeze(&dev->ctrl);
|
|
|
- nvme_dev_add(dev);
|
|
|
+ /* hit this only when allocate tagset fails */
|
|
|
+ if (nvme_dev_add(dev))
|
|
|
+ new_state = NVME_CTRL_ADMIN_ONLY;
|
|
|
nvme_unfreeze(&dev->ctrl);
|
|
|
}
|
|
|
|
|
|
- if (!nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_LIVE)) {
|
|
|
- dev_warn(dev->ctrl.device, "failed to mark controller live\n");
|
|
|
+ /*
|
|
|
+ * If only admin queue live, keep it to do further investigation or
|
|
|
+ * recovery.
|
|
|
+ */
|
|
|
+ if (!nvme_change_ctrl_state(&dev->ctrl, new_state)) {
|
|
|
+ dev_warn(dev->ctrl.device,
|
|
|
+ "failed to mark controller state %d\n", new_state);
|
|
|
goto out;
|
|
|
}
|
|
|
|