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: Jianchao Wang <jianchao.w.wang@oracle.com> Reviewed-by: Keith Busch <keith.busch@intel.com> [hch: fixed to pass a s16 and clean up the comment] Signed-off-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
parent
e9a9853c23
commit
a8e3e0bb74
@ -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,
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
* 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)
|
|||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user