Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 949928c1 authored by Keith Busch's avatar Keith Busch Committed by Jens Axboe
Browse files

NVMe: Fix possible queue use after freed



This notifies blk-mq when the tag set contains a different number of
queues prior to freeing unused ones that the request queue points to.

Signed-off-by: default avatarKeith Busch <keith.busch@intel.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarJens Axboe <axboe@fb.com>
parent 868f2f0b
Loading
Loading
Loading
Loading
+9 −5
Original line number Diff line number Diff line
@@ -1381,7 +1381,7 @@ static int nvme_kthread(void *data)

static int nvme_create_io_queues(struct nvme_dev *dev)
{
	unsigned i;
	unsigned i, max;
	int ret = 0;

	for (i = dev->queue_count; i <= dev->max_qid; i++) {
@@ -1391,7 +1391,8 @@ static int nvme_create_io_queues(struct nvme_dev *dev)
		}
	}

	for (i = dev->online_queues; i <= dev->queue_count - 1; i++) {
	max = min(dev->max_qid, dev->queue_count - 1);
	for (i = dev->online_queues; i <= max; i++) {
		ret = nvme_create_queue(dev->queues[i], i);
		if (ret) {
			nvme_free_queues(dev, i);
@@ -1548,9 +1549,6 @@ static int nvme_setup_io_queues(struct nvme_dev *dev)
		adminq->cq_vector = -1;
		goto free_queues;
	}

	/* Free previously allocated queues that are no longer usable */
	nvme_free_queues(dev, nr_io_queues + 1);
	return nvme_create_io_queues(dev);

 free_queues:
@@ -1684,7 +1682,13 @@ static int nvme_dev_add(struct nvme_dev *dev)
		if (blk_mq_alloc_tag_set(&dev->tagset))
			return 0;
		dev->ctrl.tagset = &dev->tagset;
	} else {
		blk_mq_update_nr_hw_queues(&dev->tagset, dev->online_queues - 1);

		/* Free previously allocated queues that are no longer usable */
		nvme_free_queues(dev, dev->online_queues);
	}

	queue_work(nvme_workq, &dev->scan_work);
	return 0;
}