Commit a8e3e0bb authored by Jianchao Wang's avatar Jianchao Wang Committed by Christoph Hellwig

nvme-pci: set nvmeq->cq_vector after alloc cq/sq

Set cq_vector after alloc cq/sq, otherwise nvme_suspend_queue will invoke
free_irq for it and cause a 'Trying to free already-free IRQ  xxx'
warning if the create CQ/SQ command times out.
Signed-off-by: default avatarJianchao Wang <jianchao.w.wang@oracle.com>
Reviewed-by: default avatarKeith Busch <keith.busch@intel.com>
[hch: fixed to pass a s16 and clean up the comment]
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent e9a9853c
...@@ -1076,7 +1076,7 @@ static int adapter_delete_queue(struct nvme_dev *dev, u8 opcode, u16 id) ...@@ -1076,7 +1076,7 @@ static int adapter_delete_queue(struct nvme_dev *dev, u8 opcode, u16 id)
} }
static int adapter_alloc_cq(struct nvme_dev *dev, u16 qid, static int adapter_alloc_cq(struct nvme_dev *dev, u16 qid,
struct nvme_queue *nvmeq) struct nvme_queue *nvmeq, s16 vector)
{ {
struct nvme_command c; struct nvme_command c;
int flags = NVME_QUEUE_PHYS_CONTIG | NVME_CQ_IRQ_ENABLED; int flags = NVME_QUEUE_PHYS_CONTIG | NVME_CQ_IRQ_ENABLED;
...@@ -1091,7 +1091,7 @@ static int adapter_alloc_cq(struct nvme_dev *dev, u16 qid, ...@@ -1091,7 +1091,7 @@ static int adapter_alloc_cq(struct nvme_dev *dev, u16 qid,
c.create_cq.cqid = cpu_to_le16(qid); c.create_cq.cqid = cpu_to_le16(qid);
c.create_cq.qsize = cpu_to_le16(nvmeq->q_depth - 1); c.create_cq.qsize = cpu_to_le16(nvmeq->q_depth - 1);
c.create_cq.cq_flags = cpu_to_le16(flags); c.create_cq.cq_flags = cpu_to_le16(flags);
c.create_cq.irq_vector = cpu_to_le16(nvmeq->cq_vector); c.create_cq.irq_vector = cpu_to_le16(vector);
return nvme_submit_sync_cmd(dev->ctrl.admin_q, &c, NULL, 0); return nvme_submit_sync_cmd(dev->ctrl.admin_q, &c, NULL, 0);
} }
...@@ -1466,6 +1466,7 @@ static int nvme_create_queue(struct nvme_queue *nvmeq, int qid) ...@@ -1466,6 +1466,7 @@ static int nvme_create_queue(struct nvme_queue *nvmeq, int qid)
{ {
struct nvme_dev *dev = nvmeq->dev; struct nvme_dev *dev = nvmeq->dev;
int result; int result;
s16 vector;
if (dev->cmb && use_cmb_sqes && (dev->cmbsz & NVME_CMBSZ_SQS)) { if (dev->cmb && use_cmb_sqes && (dev->cmbsz & NVME_CMBSZ_SQS)) {
unsigned offset = (qid - 1) * roundup(SQ_SIZE(nvmeq->q_depth), unsigned offset = (qid - 1) * roundup(SQ_SIZE(nvmeq->q_depth),
...@@ -1478,15 +1479,21 @@ static int nvme_create_queue(struct nvme_queue *nvmeq, int qid) ...@@ -1478,15 +1479,21 @@ static int nvme_create_queue(struct nvme_queue *nvmeq, int qid)
* A queue's vector matches the queue identifier unless the controller * A queue's vector matches the queue identifier unless the controller
* has only one vector available. * has only one vector available.
*/ */
nvmeq->cq_vector = dev->num_vecs == 1 ? 0 : qid; vector = dev->num_vecs == 1 ? 0 : qid;
result = adapter_alloc_cq(dev, qid, nvmeq); result = adapter_alloc_cq(dev, qid, nvmeq, vector);
if (result < 0) if (result < 0)
goto release_vector; goto out;
result = adapter_alloc_sq(dev, qid, nvmeq); result = adapter_alloc_sq(dev, qid, nvmeq);
if (result < 0) if (result < 0)
goto release_cq; goto release_cq;
/*
* Set cq_vector after alloc cq/sq, otherwise nvme_suspend_queue will
* invoke free_irq for it and cause a 'Trying to free already-free IRQ
* xxx' warning if the create CQ/SQ command times out.
*/
nvmeq->cq_vector = vector;
nvme_init_queue(nvmeq, qid); nvme_init_queue(nvmeq, qid);
result = queue_request_irq(nvmeq); result = queue_request_irq(nvmeq);
if (result < 0) if (result < 0)
...@@ -1494,13 +1501,13 @@ static int nvme_create_queue(struct nvme_queue *nvmeq, int qid) ...@@ -1494,13 +1501,13 @@ static int nvme_create_queue(struct nvme_queue *nvmeq, int qid)
return result; return result;
release_sq: release_sq:
nvmeq->cq_vector = -1;
dev->online_queues--; dev->online_queues--;
adapter_delete_sq(dev, qid); adapter_delete_sq(dev, qid);
release_cq: release_cq:
adapter_delete_cq(dev, qid); adapter_delete_cq(dev, qid);
release_vector: out:
nvmeq->cq_vector = -1;
return result; return result;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment