summaryrefslogtreecommitdiff
path: root/drivers/nvme/host/pci.c
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2025-03-13 09:41:57 -0600
committerJens Axboe <axboe@kernel.dk>2025-03-13 09:41:57 -0600
commita9381351dd6c52bf465233cae5f50da227834607 (patch)
tree01fd256327f2655143e209544f9e994b4c7917cd /drivers/nvme/host/pci.c
parent9bce6b5f8987678b9c6c1fe433af6b5fe41feadc (diff)
parent39393f5c5c795992507aa5005a9d58396a5b07f1 (diff)
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
Diffstat (limited to 'drivers/nvme/host/pci.c')
-rw-r--r--drivers/nvme/host/pci.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 75de86e235ad..3ad7f197c808 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -1412,9 +1412,20 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req)
struct nvme_dev *dev = nvmeq->dev;
struct request *abort_req;
struct nvme_command cmd = { };
+ struct pci_dev *pdev = to_pci_dev(dev->dev);
u32 csts = readl(dev->bar + NVME_REG_CSTS);
u8 opcode;
+ /*
+ * Shutdown the device immediately if we see it is disconnected. This
+ * unblocks PCIe error handling if the nvme driver is waiting in
+ * error_resume for a device that has been removed. We can't unbind the
+ * driver while the driver's error callback is waiting to complete, so
+ * we're relying on a timeout to break that deadlock if a removal
+ * occurs while reset work is running.
+ */
+ if (pci_dev_is_disconnected(pdev))
+ nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_DELETING);
if (nvme_state_terminal(&dev->ctrl))
goto disable;
@@ -1422,7 +1433,7 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req)
* the recovery mechanism will surely fail.
*/
mb();
- if (pci_channel_offline(to_pci_dev(dev->dev)))
+ if (pci_channel_offline(pdev))
return BLK_EH_RESET_TIMER;
/*