aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith Busch <keith.busch@intel.com>2015-01-07 20:55:49 -0500
committerJens Axboe <axboe@fb.com>2015-01-08 11:00:32 -0500
commitea191d2f36b0f577ce5377c3e72aedc34282969d (patch)
tree27ff7ee0f1971cea41c38a7c3d265a3f4a106263
parentc917dfe52834979610d45022226445d1dc7c67d8 (diff)
NVMe: Reference count admin queue usage
Since there is no gendisk associated with the admin queue, the driver needs to hold a reference to it until all open references to the controller are closed. This also combines queue cleanup with freeing the tag set since these should not be separate. Signed-off-by: Keith Busch <keith.busch@intel.com> Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r--drivers/block/nvme-core.c28
1 files changed, 14 insertions, 14 deletions
diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c
index 286fa4cfc937..beb8d48f8560 100644
--- a/drivers/block/nvme-core.c
+++ b/drivers/block/nvme-core.c
@@ -1369,6 +1369,14 @@ static struct blk_mq_ops nvme_mq_ops = {
1369 .timeout = nvme_timeout, 1369 .timeout = nvme_timeout,
1370}; 1370};
1371 1371
1372static void nvme_dev_remove_admin(struct nvme_dev *dev)
1373{
1374 if (dev->admin_q && !blk_queue_dying(dev->admin_q)) {
1375 blk_cleanup_queue(dev->admin_q);
1376 blk_mq_free_tag_set(&dev->admin_tagset);
1377 }
1378}
1379
1372static int nvme_alloc_admin_tags(struct nvme_dev *dev) 1380static int nvme_alloc_admin_tags(struct nvme_dev *dev)
1373{ 1381{
1374 if (!dev->admin_q) { 1382 if (!dev->admin_q) {
@@ -1388,17 +1396,15 @@ static int nvme_alloc_admin_tags(struct nvme_dev *dev)
1388 blk_mq_free_tag_set(&dev->admin_tagset); 1396 blk_mq_free_tag_set(&dev->admin_tagset);
1389 return -ENOMEM; 1397 return -ENOMEM;
1390 } 1398 }
1399 if (!blk_get_queue(dev->admin_q)) {
1400 nvme_dev_remove_admin(dev);
1401 return -ENODEV;
1402 }
1391 } 1403 }
1392 1404
1393 return 0; 1405 return 0;
1394} 1406}
1395 1407
1396static void nvme_free_admin_tags(struct nvme_dev *dev)
1397{
1398 if (dev->admin_q)
1399 blk_mq_free_tag_set(&dev->admin_tagset);
1400}
1401
1402static int nvme_configure_admin_queue(struct nvme_dev *dev) 1408static int nvme_configure_admin_queue(struct nvme_dev *dev)
1403{ 1409{
1404 int result; 1410 int result;
@@ -1465,7 +1471,7 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev)
1465 return result; 1471 return result;
1466 1472
1467 free_tags: 1473 free_tags:
1468 nvme_free_admin_tags(dev); 1474 nvme_dev_remove_admin(dev);
1469 free_nvmeq: 1475 free_nvmeq:
1470 nvme_free_queues(dev, 0); 1476 nvme_free_queues(dev, 0);
1471 return result; 1477 return result;
@@ -2415,12 +2421,6 @@ static void nvme_dev_shutdown(struct nvme_dev *dev)
2415 nvme_dev_unmap(dev); 2421 nvme_dev_unmap(dev);
2416} 2422}
2417 2423
2418static void nvme_dev_remove_admin(struct nvme_dev *dev)
2419{
2420 if (dev->admin_q && !blk_queue_dying(dev->admin_q))
2421 blk_cleanup_queue(dev->admin_q);
2422}
2423
2424static void nvme_dev_remove(struct nvme_dev *dev) 2424static void nvme_dev_remove(struct nvme_dev *dev)
2425{ 2425{
2426 struct nvme_ns *ns; 2426 struct nvme_ns *ns;
@@ -2510,6 +2510,7 @@ static void nvme_free_dev(struct kref *kref)
2510 nvme_free_namespaces(dev); 2510 nvme_free_namespaces(dev);
2511 nvme_release_instance(dev); 2511 nvme_release_instance(dev);
2512 blk_mq_free_tag_set(&dev->tagset); 2512 blk_mq_free_tag_set(&dev->tagset);
2513 blk_put_queue(dev->admin_q);
2513 kfree(dev->queues); 2514 kfree(dev->queues);
2514 kfree(dev->entry); 2515 kfree(dev->entry);
2515 kfree(dev); 2516 kfree(dev);
@@ -2795,7 +2796,6 @@ static void nvme_remove(struct pci_dev *pdev)
2795 nvme_dev_shutdown(dev); 2796 nvme_dev_shutdown(dev);
2796 nvme_dev_remove_admin(dev); 2797 nvme_dev_remove_admin(dev);
2797 nvme_free_queues(dev, 0); 2798 nvme_free_queues(dev, 0);
2798 nvme_free_admin_tags(dev);
2799 nvme_release_prp_pools(dev); 2799 nvme_release_prp_pools(dev);
2800 kref_put(&dev->kref, nvme_free_dev); 2800 kref_put(&dev->kref, nvme_free_dev);
2801} 2801}