Skip to content

Commit 39393f5

Browse files
damien-lemoalkeithbusch
authored andcommitted
nvmet: pci-epf: Do not add an IRQ vector if not needed
The function nvmet_pci_epf_create_cq() always unconditionally calls nvmet_pci_epf_add_irq_vector() to add an IRQ vector for a completion queue. But this is not correct if the host requested the creation of a completion queue for polling, without an IRQ vector specified (i.e. the flag NVME_CQ_IRQ_ENABLED is not set). Fix this by calling nvmet_pci_epf_add_irq_vector() and setting the queue flag NVMET_PCI_EPF_Q_IRQ_ENABLED for the cq only if NVME_CQ_IRQ_ENABLED is set. While at it, also fix the error path to add the missing removal of the added IRQ vector if nvmet_cq_create() fails. Fixes: 0faa0fe ("nvmet: New NVMe PCI endpoint function target driver") Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Keith Busch <kbusch@kernel.org>
1 parent bf9b802 commit 39393f5

File tree

1 file changed

+7
-8
lines changed

1 file changed

+7
-8
lines changed

drivers/nvme/target/pci-epf.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,9 +1271,6 @@ static u16 nvmet_pci_epf_create_cq(struct nvmet_ctrl *tctrl,
12711271
if (!(flags & NVME_QUEUE_PHYS_CONTIG))
12721272
return NVME_SC_INVALID_QUEUE | NVME_STATUS_DNR;
12731273

1274-
if (flags & NVME_CQ_IRQ_ENABLED)
1275-
set_bit(NVMET_PCI_EPF_Q_IRQ_ENABLED, &cq->flags);
1276-
12771274
cq->pci_addr = pci_addr;
12781275
cq->qid = cqid;
12791276
cq->depth = qsize + 1;
@@ -1290,10 +1287,11 @@ static u16 nvmet_pci_epf_create_cq(struct nvmet_ctrl *tctrl,
12901287
cq->qes = ctrl->io_cqes;
12911288
cq->pci_size = cq->qes * cq->depth;
12921289

1293-
cq->iv = nvmet_pci_epf_add_irq_vector(ctrl, vector);
1294-
if (!cq->iv) {
1295-
status = NVME_SC_INTERNAL | NVME_STATUS_DNR;
1296-
goto err;
1290+
if (flags & NVME_CQ_IRQ_ENABLED) {
1291+
cq->iv = nvmet_pci_epf_add_irq_vector(ctrl, vector);
1292+
if (!cq->iv)
1293+
return NVME_SC_INTERNAL | NVME_STATUS_DNR;
1294+
set_bit(NVMET_PCI_EPF_Q_IRQ_ENABLED, &cq->flags);
12971295
}
12981296

12991297
status = nvmet_cq_create(tctrl, &cq->nvme_cq, cqid, cq->depth);
@@ -1308,7 +1306,8 @@ static u16 nvmet_pci_epf_create_cq(struct nvmet_ctrl *tctrl,
13081306
return NVME_SC_SUCCESS;
13091307

13101308
err:
1311-
clear_bit(NVMET_PCI_EPF_Q_IRQ_ENABLED, &cq->flags);
1309+
if (test_and_clear_bit(NVMET_PCI_EPF_Q_IRQ_ENABLED, &cq->flags))
1310+
nvmet_pci_epf_remove_irq_vector(ctrl, cq->vector);
13121311
return status;
13131312
}
13141313

0 commit comments

Comments
 (0)