nvme/pci: Don't free queues on error
The nvme_remove function tears down all allocated resources in the correct order, so no need to free queues on error during initialization. This fixes possible use-after-free errors when queues are still associated with a blk-mq hctx. Reported-by: Scott Bauer <scott.bauer@intel.com> Tested-by: Scott Bauer <scott.bauer@intel.com> Signed-off-by: Keith Busch <keith.busch@intel.com> Reviewed-by: Sagi Grimberg <sagi@grimbeg.me> Reviewed-by: Christoph Hellwig <hch@lst.de> Cc: stable@vger.kernel.org Signed-off-by: Jens Axboe <axboe@fb.com>
This commit is contained in:
parent
959401aa2b
commit
d48756228e
@ -1242,20 +1242,16 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev)
|
|||||||
|
|
||||||
result = nvme_enable_ctrl(&dev->ctrl, cap);
|
result = nvme_enable_ctrl(&dev->ctrl, cap);
|
||||||
if (result)
|
if (result)
|
||||||
goto free_nvmeq;
|
return result;
|
||||||
|
|
||||||
nvmeq->cq_vector = 0;
|
nvmeq->cq_vector = 0;
|
||||||
result = queue_request_irq(nvmeq);
|
result = queue_request_irq(nvmeq);
|
||||||
if (result) {
|
if (result) {
|
||||||
nvmeq->cq_vector = -1;
|
nvmeq->cq_vector = -1;
|
||||||
goto free_nvmeq;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
free_nvmeq:
|
|
||||||
nvme_free_queues(dev, 0);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool nvme_should_reset(struct nvme_dev *dev, u32 csts)
|
static bool nvme_should_reset(struct nvme_dev *dev, u32 csts)
|
||||||
@ -1317,10 +1313,8 @@ static int nvme_create_io_queues(struct nvme_dev *dev)
|
|||||||
max = min(dev->max_qid, dev->queue_count - 1);
|
max = min(dev->max_qid, dev->queue_count - 1);
|
||||||
for (i = dev->online_queues; i <= max; i++) {
|
for (i = dev->online_queues; i <= max; i++) {
|
||||||
ret = nvme_create_queue(dev->queues[i], i);
|
ret = nvme_create_queue(dev->queues[i], i);
|
||||||
if (ret) {
|
if (ret)
|
||||||
nvme_free_queues(dev, i);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1460,13 +1454,9 @@ static int nvme_setup_io_queues(struct nvme_dev *dev)
|
|||||||
result = queue_request_irq(adminq);
|
result = queue_request_irq(adminq);
|
||||||
if (result) {
|
if (result) {
|
||||||
adminq->cq_vector = -1;
|
adminq->cq_vector = -1;
|
||||||
goto free_queues;
|
return result;
|
||||||
}
|
}
|
||||||
return nvme_create_io_queues(dev);
|
return nvme_create_io_queues(dev);
|
||||||
|
|
||||||
free_queues:
|
|
||||||
nvme_free_queues(dev, 1);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nvme_del_queue_end(struct request *req, int error)
|
static void nvme_del_queue_end(struct request *req, int error)
|
||||||
|
Loading…
Reference in New Issue
Block a user