Skip to content

Commit a938135

Browse files
committed
Merge tag 'nvme-6.14-2025-03-13' of git://git.infradead.org/nvme into block-6.14
Pull NVMe fixes from Keith: "nvme fixes for Linux 6.14 - Concurrent pci error and hotplug handling fix (Keith) - Endpoint function fixes (Damien)" * tag 'nvme-6.14-2025-03-13' of git://git.infradead.org/nvme: nvmet: pci-epf: Do not add an IRQ vector if not needed nvmet: pci-epf: Set NVMET_PCI_EPF_Q_LIVE when a queue is fully created nvme-pci: fix stuck reset on concurrent DPC and HP
2 parents 9bce6b5 + 39393f5 commit a938135

File tree

2 files changed

+26
-15
lines changed

2 files changed

+26
-15
lines changed

drivers/nvme/host/pci.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1412,17 +1412,28 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req)
14121412
struct nvme_dev *dev = nvmeq->dev;
14131413
struct request *abort_req;
14141414
struct nvme_command cmd = { };
1415+
struct pci_dev *pdev = to_pci_dev(dev->dev);
14151416
u32 csts = readl(dev->bar + NVME_REG_CSTS);
14161417
u8 opcode;
14171418

1419+
/*
1420+
* Shutdown the device immediately if we see it is disconnected. This
1421+
* unblocks PCIe error handling if the nvme driver is waiting in
1422+
* error_resume for a device that has been removed. We can't unbind the
1423+
* driver while the driver's error callback is waiting to complete, so
1424+
* we're relying on a timeout to break that deadlock if a removal
1425+
* occurs while reset work is running.
1426+
*/
1427+
if (pci_dev_is_disconnected(pdev))
1428+
nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_DELETING);
14181429
if (nvme_state_terminal(&dev->ctrl))
14191430
goto disable;
14201431

14211432
/* If PCI error recovery process is happening, we cannot reset or
14221433
* the recovery mechanism will surely fail.
14231434
*/
14241435
mb();
1425-
if (pci_channel_offline(to_pci_dev(dev->dev)))
1436+
if (pci_channel_offline(pdev))
14261437
return BLK_EH_RESET_TIMER;
14271438

14281439
/*

drivers/nvme/target/pci-epf.c

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,15 +1265,12 @@ static u16 nvmet_pci_epf_create_cq(struct nvmet_ctrl *tctrl,
12651265
struct nvmet_pci_epf_queue *cq = &ctrl->cq[cqid];
12661266
u16 status;
12671267

1268-
if (test_and_set_bit(NVMET_PCI_EPF_Q_LIVE, &cq->flags))
1268+
if (test_bit(NVMET_PCI_EPF_Q_LIVE, &cq->flags))
12691269
return NVME_SC_QID_INVALID | NVME_STATUS_DNR;
12701270

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,24 +1287,27 @@ 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);
13001298
if (status != NVME_SC_SUCCESS)
13011299
goto err;
13021300

1301+
set_bit(NVMET_PCI_EPF_Q_LIVE, &cq->flags);
1302+
13031303
dev_dbg(ctrl->dev, "CQ[%u]: %u entries of %zu B, IRQ vector %u\n",
13041304
cqid, qsize, cq->qes, cq->vector);
13051305

13061306
return NVME_SC_SUCCESS;
13071307

13081308
err:
1309-
clear_bit(NVMET_PCI_EPF_Q_IRQ_ENABLED, &cq->flags);
1310-
clear_bit(NVMET_PCI_EPF_Q_LIVE, &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);
13111311
return status;
13121312
}
13131313

@@ -1333,7 +1333,7 @@ static u16 nvmet_pci_epf_create_sq(struct nvmet_ctrl *tctrl,
13331333
struct nvmet_pci_epf_queue *sq = &ctrl->sq[sqid];
13341334
u16 status;
13351335

1336-
if (test_and_set_bit(NVMET_PCI_EPF_Q_LIVE, &sq->flags))
1336+
if (test_bit(NVMET_PCI_EPF_Q_LIVE, &sq->flags))
13371337
return NVME_SC_QID_INVALID | NVME_STATUS_DNR;
13381338

13391339
if (!(flags & NVME_QUEUE_PHYS_CONTIG))
@@ -1355,7 +1355,7 @@ static u16 nvmet_pci_epf_create_sq(struct nvmet_ctrl *tctrl,
13551355

13561356
status = nvmet_sq_create(tctrl, &sq->nvme_sq, sqid, sq->depth);
13571357
if (status != NVME_SC_SUCCESS)
1358-
goto out_clear_bit;
1358+
return status;
13591359

13601360
sq->iod_wq = alloc_workqueue("sq%d_wq", WQ_UNBOUND,
13611361
min_t(int, sq->depth, WQ_MAX_ACTIVE), sqid);
@@ -1365,15 +1365,15 @@ static u16 nvmet_pci_epf_create_sq(struct nvmet_ctrl *tctrl,
13651365
goto out_destroy_sq;
13661366
}
13671367

1368+
set_bit(NVMET_PCI_EPF_Q_LIVE, &sq->flags);
1369+
13681370
dev_dbg(ctrl->dev, "SQ[%u]: %u entries of %zu B\n",
13691371
sqid, qsize, sq->qes);
13701372

13711373
return NVME_SC_SUCCESS;
13721374

13731375
out_destroy_sq:
13741376
nvmet_sq_destroy(&sq->nvme_sq);
1375-
out_clear_bit:
1376-
clear_bit(NVMET_PCI_EPF_Q_LIVE, &sq->flags);
13771377
return status;
13781378
}
13791379

0 commit comments

Comments
 (0)