Skip to content

Commit

Permalink
NVMe: Reference count admin queue usage
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Keith Busch authored and Jens Axboe committed Jan 8, 2015
1 parent c917dfe commit ea191d2
Showing 1 changed file with 14 additions and 14 deletions.
28 changes: 14 additions & 14 deletions drivers/block/nvme-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1369,6 +1369,14 @@ static struct blk_mq_ops nvme_mq_ops = {
.timeout = nvme_timeout,
};

static void nvme_dev_remove_admin(struct nvme_dev *dev)
{
if (dev->admin_q && !blk_queue_dying(dev->admin_q)) {
blk_cleanup_queue(dev->admin_q);
blk_mq_free_tag_set(&dev->admin_tagset);
}
}

static int nvme_alloc_admin_tags(struct nvme_dev *dev)
{
if (!dev->admin_q) {
Expand All @@ -1388,17 +1396,15 @@ static int nvme_alloc_admin_tags(struct nvme_dev *dev)
blk_mq_free_tag_set(&dev->admin_tagset);
return -ENOMEM;
}
if (!blk_get_queue(dev->admin_q)) {
nvme_dev_remove_admin(dev);
return -ENODEV;
}
}

return 0;
}

static void nvme_free_admin_tags(struct nvme_dev *dev)
{
if (dev->admin_q)
blk_mq_free_tag_set(&dev->admin_tagset);
}

static int nvme_configure_admin_queue(struct nvme_dev *dev)
{
int result;
Expand Down Expand Up @@ -1465,7 +1471,7 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev)
return result;

free_tags:
nvme_free_admin_tags(dev);
nvme_dev_remove_admin(dev);
free_nvmeq:
nvme_free_queues(dev, 0);
return result;
Expand Down Expand Up @@ -2415,12 +2421,6 @@ static void nvme_dev_shutdown(struct nvme_dev *dev)
nvme_dev_unmap(dev);
}

static void nvme_dev_remove_admin(struct nvme_dev *dev)
{
if (dev->admin_q && !blk_queue_dying(dev->admin_q))
blk_cleanup_queue(dev->admin_q);
}

static void nvme_dev_remove(struct nvme_dev *dev)
{
struct nvme_ns *ns;
Expand Down Expand Up @@ -2510,6 +2510,7 @@ static void nvme_free_dev(struct kref *kref)
nvme_free_namespaces(dev);
nvme_release_instance(dev);
blk_mq_free_tag_set(&dev->tagset);
blk_put_queue(dev->admin_q);
kfree(dev->queues);
kfree(dev->entry);
kfree(dev);
Expand Down Expand Up @@ -2795,7 +2796,6 @@ static void nvme_remove(struct pci_dev *pdev)
nvme_dev_shutdown(dev);
nvme_dev_remove_admin(dev);
nvme_free_queues(dev, 0);
nvme_free_admin_tags(dev);
nvme_release_prp_pools(dev);
kref_put(&dev->kref, nvme_free_dev);
}
Expand Down

0 comments on commit ea191d2

Please sign in to comment.