Commit a9381351 authored by Jens Axboe's avatar Jens Axboe
Browse files

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
parents 9bce6b5f 39393f5c
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -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;

	/*
+14 −14
Original line number Diff line number Diff line
@@ -1265,15 +1265,12 @@ static u16 nvmet_pci_epf_create_cq(struct nvmet_ctrl *tctrl,
	struct nvmet_pci_epf_queue *cq = &ctrl->cq[cqid];
	u16 status;

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

	if (!(flags & NVME_QUEUE_PHYS_CONTIG))
		return NVME_SC_INVALID_QUEUE | NVME_STATUS_DNR;

	if (flags & NVME_CQ_IRQ_ENABLED)
		set_bit(NVMET_PCI_EPF_Q_IRQ_ENABLED, &cq->flags);

	cq->pci_addr = pci_addr;
	cq->qid = cqid;
	cq->depth = qsize + 1;
@@ -1290,24 +1287,27 @@ static u16 nvmet_pci_epf_create_cq(struct nvmet_ctrl *tctrl,
		cq->qes = ctrl->io_cqes;
	cq->pci_size = cq->qes * cq->depth;

	if (flags & NVME_CQ_IRQ_ENABLED) {
		cq->iv = nvmet_pci_epf_add_irq_vector(ctrl, vector);
	if (!cq->iv) {
		status = NVME_SC_INTERNAL | NVME_STATUS_DNR;
		goto err;
		if (!cq->iv)
			return NVME_SC_INTERNAL | NVME_STATUS_DNR;
		set_bit(NVMET_PCI_EPF_Q_IRQ_ENABLED, &cq->flags);
	}

	status = nvmet_cq_create(tctrl, &cq->nvme_cq, cqid, cq->depth);
	if (status != NVME_SC_SUCCESS)
		goto err;

	set_bit(NVMET_PCI_EPF_Q_LIVE, &cq->flags);

	dev_dbg(ctrl->dev, "CQ[%u]: %u entries of %zu B, IRQ vector %u\n",
		cqid, qsize, cq->qes, cq->vector);

	return NVME_SC_SUCCESS;

err:
	clear_bit(NVMET_PCI_EPF_Q_IRQ_ENABLED, &cq->flags);
	clear_bit(NVMET_PCI_EPF_Q_LIVE, &cq->flags);
	if (test_and_clear_bit(NVMET_PCI_EPF_Q_IRQ_ENABLED, &cq->flags))
		nvmet_pci_epf_remove_irq_vector(ctrl, cq->vector);
	return status;
}

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

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

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

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

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

	set_bit(NVMET_PCI_EPF_Q_LIVE, &sq->flags);

	dev_dbg(ctrl->dev, "SQ[%u]: %u entries of %zu B\n",
		sqid, qsize, sq->qes);

@@ -1372,8 +1374,6 @@ static u16 nvmet_pci_epf_create_sq(struct nvmet_ctrl *tctrl,

out_destroy_sq:
	nvmet_sq_destroy(&sq->nvme_sq);
out_clear_bit:
	clear_bit(NVMET_PCI_EPF_Q_LIVE, &sq->flags);
	return status;
}