Skip to content

Commit d72a4ca

Browse files
weiny2djbw
authored andcommitted
cxl/pci: Skip irq features if MSI/MSI-X are not supported
CXL 3.1 Section 3.1.1 states: "A Function on a CXL device must not generate INTx messages if that Function participates in CXL.cache protocol or CXL.mem protocols." The generic CXL memory driver only supports devices which use the CXL.mem protocol. The current driver attempts to allocate MSI/MSI-X vectors in anticipation of their need for mailbox interrupts or event processing. However, the above requirement does not require a device to support interrupts, only that they use MSI/MSI-X. For example, a device may disable mailbox interrupts and either be configured for firmware first or skip event processing and function. Dave Larsen reported that the following Intel / Agilex card does not support interrupts on function 0. CXL: Intel Corporation Device 0ddb (rev 01) (prog-if 10 [CXL Memory Device (CXL 2.x)]) Rather than fail device probe if interrupts are not supported; flag that irqs are not enabled and avoid features which require interrupts. Emit messages appropriate for the situation to aid in debugging should device behavior be unexpected due to a failure to allocate vectors. Note that it is possible for a device to have host based event processing through polling. However, the driver does not support polling and it is not anticipated to be generally required. Leave that functionality to a future patch if such a device comes along. Reported-by: Dave Larsen <[email protected]> Reviewed-by: Dave Jiang <[email protected]> Reviewed-by: Fan Ni <[email protected]> Signed-off-by: Ira Weiny <[email protected]> Reviewed-and-tested-by: Davidlohr Bueso <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Dan Williams <[email protected]>
1 parent c97dac5 commit d72a4ca

File tree

1 file changed

+15
-11
lines changed

1 file changed

+15
-11
lines changed

drivers/cxl/pci.c

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ static int cxl_pci_mbox_send(struct cxl_memdev_state *mds,
382382
return rc;
383383
}
384384

385-
static int cxl_pci_setup_mailbox(struct cxl_memdev_state *mds)
385+
static int cxl_pci_setup_mailbox(struct cxl_memdev_state *mds, bool irq_avail)
386386
{
387387
struct cxl_dev_state *cxlds = &mds->cxlds;
388388
const int cap = readl(cxlds->regs.mbox + CXLDEV_MBOX_CAPS_OFFSET);
@@ -441,7 +441,7 @@ static int cxl_pci_setup_mailbox(struct cxl_memdev_state *mds)
441441
INIT_DELAYED_WORK(&mds->security.poll_dwork, cxl_mbox_sanitize_work);
442442

443443
/* background command interrupts are optional */
444-
if (!(cap & CXLDEV_MBOX_CAP_BG_CMD_IRQ))
444+
if (!(cap & CXLDEV_MBOX_CAP_BG_CMD_IRQ) || !irq_avail)
445445
return 0;
446446

447447
msgnum = FIELD_GET(CXLDEV_MBOX_CAP_IRQ_MSGNUM_MASK, cap);
@@ -588,7 +588,7 @@ static int cxl_mem_alloc_event_buf(struct cxl_memdev_state *mds)
588588
return devm_add_action_or_reset(mds->cxlds.dev, free_event_buf, buf);
589589
}
590590

591-
static int cxl_alloc_irq_vectors(struct pci_dev *pdev)
591+
static bool cxl_alloc_irq_vectors(struct pci_dev *pdev)
592592
{
593593
int nvecs;
594594

@@ -605,9 +605,9 @@ static int cxl_alloc_irq_vectors(struct pci_dev *pdev)
605605
PCI_IRQ_MSIX | PCI_IRQ_MSI);
606606
if (nvecs < 1) {
607607
dev_dbg(&pdev->dev, "Failed to alloc irq vectors: %d\n", nvecs);
608-
return -ENXIO;
608+
return false;
609609
}
610-
return 0;
610+
return true;
611611
}
612612

613613
static irqreturn_t cxl_event_thread(int irq, void *id)
@@ -743,7 +743,7 @@ static bool cxl_event_int_is_fw(u8 setting)
743743
}
744744

745745
static int cxl_event_config(struct pci_host_bridge *host_bridge,
746-
struct cxl_memdev_state *mds)
746+
struct cxl_memdev_state *mds, bool irq_avail)
747747
{
748748
struct cxl_event_interrupt_policy policy;
749749
int rc;
@@ -755,6 +755,11 @@ static int cxl_event_config(struct pci_host_bridge *host_bridge,
755755
if (!host_bridge->native_cxl_error)
756756
return 0;
757757

758+
if (!irq_avail) {
759+
dev_info(mds->cxlds.dev, "No interrupt support, disable event processing.\n");
760+
return 0;
761+
}
762+
758763
rc = cxl_mem_alloc_event_buf(mds);
759764
if (rc)
760765
return rc;
@@ -789,6 +794,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
789794
struct cxl_register_map map;
790795
struct cxl_memdev *cxlmd;
791796
int i, rc, pmu_count;
797+
bool irq_avail;
792798

793799
/*
794800
* Double check the anonymous union trickery in struct cxl_regs
@@ -846,11 +852,9 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
846852
else
847853
dev_warn(&pdev->dev, "Media not active (%d)\n", rc);
848854

849-
rc = cxl_alloc_irq_vectors(pdev);
850-
if (rc)
851-
return rc;
855+
irq_avail = cxl_alloc_irq_vectors(pdev);
852856

853-
rc = cxl_pci_setup_mailbox(mds);
857+
rc = cxl_pci_setup_mailbox(mds, irq_avail);
854858
if (rc)
855859
return rc;
856860

@@ -909,7 +913,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
909913
}
910914
}
911915

912-
rc = cxl_event_config(host_bridge, mds);
916+
rc = cxl_event_config(host_bridge, mds, irq_avail);
913917
if (rc)
914918
return rc;
915919

0 commit comments

Comments
 (0)