[RESEND PATCH v4 06/11] cxl/pci: Add the PMUs after configuring events

Dave Jiang <[email protected]> Wed, 5 Aug 2026 08:59:06 -0700
Newsgroups org.kernel.vger.linux-cxl,org.kernel.vger.linux-perf-users
Message-ID <[email protected]>
cxl_pci_probe() adds the CPMU instances before configuring the event
interrupts. Both take an MSI/MSI-X vector the device names in its own
capability registers, and the spec lets a device point several capabilities
at one message number, so the two can collide.

They do not fail the same way. A failed devm_cxl_pmu_add() only breaks out
of the loop, while a failed cxl_event_config() aborts probe and the memory
device never appears. Going PMUs-first therefore lets a peripheral facility
take the vector and deny it to one that matters.

Configure events first, so a collision costs the PMU rather than the
memdev. Return 0 explicitly afterwards, since rc still holds any PMU error
that cxl_event_config() used to overwrite on the way past.

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Dave Jiang <[email protected]>
---
v4:
- New patch, ahead of the PMU dropping IRQF_SHARED. Without this that
  change can turn a shared vector into a probe failure for the whole
  memdev rather than a missing PMU (sashiko-bot).
---
 drivers/cxl/pci.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
index 267c679b0b3c..975d32716762 100644
--- a/drivers/cxl/pci.c
+++ b/drivers/cxl/pci.c
@@ -894,6 +894,10 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	if (rc)
 		dev_dbg(&pdev->dev, "No CXL FWCTL setup\n");
 
+	rc = cxl_event_config(host_bridge, mds, irq_avail);
+	if (rc)
+		return rc;
+
 	pmu_count = cxl_count_regblock(pdev, CXL_REGLOC_RBI_PMU);
 	if (pmu_count < 0)
 		return pmu_count;
@@ -920,13 +924,10 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 		}
 	}
 
-	rc = cxl_event_config(host_bridge, mds, irq_avail);
-	if (rc)
-		return rc;
-
 	pci_save_state(pdev);
 
-	return rc;
+	/* A missing PMU is not fatal, the memdev is still usable */
+	return 0;
 }
 
 static const struct pci_device_id cxl_mem_pci_tbl[] = {
-- 
2.54.0