aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/block/nvme-core.c34
1 files changed, 20 insertions, 14 deletions
diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c
index beb8d48f8560..5fcb993fc6c9 100644
--- a/drivers/block/nvme-core.c
+++ b/drivers/block/nvme-core.c
@@ -1183,6 +1183,8 @@ static void nvme_disable_queue(struct nvme_dev *dev, int qid)
1183 adapter_delete_sq(dev, qid); 1183 adapter_delete_sq(dev, qid);
1184 adapter_delete_cq(dev, qid); 1184 adapter_delete_cq(dev, qid);
1185 } 1185 }
1186 if (!qid && dev->admin_q)
1187 blk_mq_freeze_queue_start(dev->admin_q);
1186 nvme_clear_queue(nvmeq); 1188 nvme_clear_queue(nvmeq);
1187} 1189}
1188 1190
@@ -1400,7 +1402,8 @@ static int nvme_alloc_admin_tags(struct nvme_dev *dev)
1400 nvme_dev_remove_admin(dev); 1402 nvme_dev_remove_admin(dev);
1401 return -ENODEV; 1403 return -ENODEV;
1402 } 1404 }
1403 } 1405 } else
1406 blk_mq_unfreeze_queue(dev->admin_q);
1404 1407
1405 return 0; 1408 return 0;
1406} 1409}
@@ -1459,19 +1462,13 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev)
1459 if (result) 1462 if (result)
1460 goto free_nvmeq; 1463 goto free_nvmeq;
1461 1464
1462 result = nvme_alloc_admin_tags(dev);
1463 if (result)
1464 goto free_nvmeq;
1465
1466 nvmeq->cq_vector = 0; 1465 nvmeq->cq_vector = 0;
1467 result = queue_request_irq(dev, nvmeq, nvmeq->irqname); 1466 result = queue_request_irq(dev, nvmeq, nvmeq->irqname);
1468 if (result) 1467 if (result)
1469 goto free_tags; 1468 goto free_nvmeq;
1470 1469
1471 return result; 1470 return result;
1472 1471
1473 free_tags:
1474 nvme_dev_remove_admin(dev);
1475 free_nvmeq: 1472 free_nvmeq:
1476 nvme_free_queues(dev, 0); 1473 nvme_free_queues(dev, 0);
1477 return result; 1474 return result;
@@ -2256,13 +2253,18 @@ static void nvme_wait_dq(struct nvme_delq_ctx *dq, struct nvme_dev *dev)
2256 break; 2253 break;
2257 if (!schedule_timeout(ADMIN_TIMEOUT) || 2254 if (!schedule_timeout(ADMIN_TIMEOUT) ||
2258 fatal_signal_pending(current)) { 2255 fatal_signal_pending(current)) {
2256 /*
2257 * Disable the controller first since we can't trust it
2258 * at this point, but leave the admin queue enabled
2259 * until all queue deletion requests are flushed.
2260 * FIXME: This may take a while if there are more h/w
2261 * queues than admin tags.
2262 */
2259 set_current_state(TASK_RUNNING); 2263 set_current_state(TASK_RUNNING);
2260
2261 nvme_disable_ctrl(dev, readq(&dev->bar->cap)); 2264 nvme_disable_ctrl(dev, readq(&dev->bar->cap));
2262 nvme_disable_queue(dev, 0); 2265 nvme_clear_queue(dev->queues[0]);
2263
2264 send_sig(SIGKILL, dq->worker->task, 1);
2265 flush_kthread_worker(dq->worker); 2266 flush_kthread_worker(dq->worker);
2267 nvme_disable_queue(dev, 0);
2266 return; 2268 return;
2267 } 2269 }
2268 } 2270 }
@@ -2339,7 +2341,6 @@ static void nvme_del_queue_start(struct kthread_work *work)
2339{ 2341{
2340 struct nvme_queue *nvmeq = container_of(work, struct nvme_queue, 2342 struct nvme_queue *nvmeq = container_of(work, struct nvme_queue,
2341 cmdinfo.work); 2343 cmdinfo.work);
2342 allow_signal(SIGKILL);
2343 if (nvme_delete_sq(nvmeq)) 2344 if (nvme_delete_sq(nvmeq))
2344 nvme_del_queue_end(nvmeq); 2345 nvme_del_queue_end(nvmeq);
2345} 2346}
@@ -2607,15 +2608,20 @@ static int nvme_dev_start(struct nvme_dev *dev)
2607 } 2608 }
2608 2609
2609 nvme_init_queue(dev->queues[0], 0); 2610 nvme_init_queue(dev->queues[0], 0);
2611 result = nvme_alloc_admin_tags(dev);
2612 if (result)
2613 goto disable;
2610 2614
2611 result = nvme_setup_io_queues(dev); 2615 result = nvme_setup_io_queues(dev);
2612 if (result) 2616 if (result)
2613 goto disable; 2617 goto free_tags;
2614 2618
2615 nvme_set_irq_hints(dev); 2619 nvme_set_irq_hints(dev);
2616 2620
2617 return result; 2621 return result;
2618 2622
2623 free_tags:
2624 nvme_dev_remove_admin(dev);
2619 disable: 2625 disable:
2620 nvme_disable_queue(dev, 0); 2626 nvme_disable_queue(dev, 0);
2621 nvme_dev_list_remove(dev); 2627 nvme_dev_list_remove(dev);