diff options
-rw-r--r-- | drivers/block/nvme-core.c | 34 |
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); |