Re: [PATCH v13 02/15] cxl: Share CXL port upstream PCI device lookup

From: Dave Jiang

Date: Thu Sep 24 2026 - 13:13:41 EST




On 9/22/26 1:39 AM, Srirangan Madhavan wrote:
> read_cdat_data() resolves a CXL port's upstream device to its backing PCI
> device. HDM cache updates need the same mapping.
>
> Factor the lookup into cxl_port_get_uport_pci_dev() and return a referenced
> PCI device to make caller ownership explicit.
>
> Signed-off-by: Srirangan Madhavan <smadhavan@xxxxxxxxxx>

Reviewed-by: Dave Jiang <dave.jiang@xxxxxxxxx>

> ---
> drivers/cxl/core/core.h | 1 +
> drivers/cxl/core/pci.c | 23 ++++++-----------------
> drivers/cxl/core/port.c | 26 ++++++++++++++++++++++++++
> 3 files changed, 33 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h
> index 35eaf636adc9..983d7690c3a5 100644
> --- a/drivers/cxl/core/core.h
> +++ b/drivers/cxl/core/core.h
> @@ -157,6 +157,7 @@ long cxl_pci_get_latency(struct pci_dev *pdev);
> int cxl_pci_get_bandwidth(struct pci_dev *pdev, struct access_coordinate *c);
> int cxl_port_get_switch_dport_bandwidth(struct cxl_port *port,
> struct access_coordinate *c);
> +struct pci_dev *cxl_port_get_uport_pci_dev(struct cxl_port *port);
>
> static inline struct device *port_to_host(struct cxl_port *port)
> {
> diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
> index 9d807c1a002c..bf7fc77626d9 100644
> --- a/drivers/cxl/core/pci.c
> +++ b/drivers/cxl/core/pci.c
> @@ -564,26 +564,13 @@ static unsigned char cdat_checksum(void *buf, size_t size)
> */
> void read_cdat_data(struct cxl_port *port)
> {
> - struct device *uport = port->uport_dev;
> + struct pci_dev *pdev = cxl_port_get_uport_pci_dev(port);
> struct device *dev = &port->dev;
> struct pci_doe_mb *doe_mb;
> - struct pci_dev *pdev = NULL;
> - struct cxl_memdev *cxlmd;
> struct cdat_doe_rsp *buf;
> size_t table_length, length;
> int rc;
>
> - if (is_cxl_memdev(uport)) {
> - struct device *host;
> -
> - cxlmd = to_cxl_memdev(uport);
> - host = cxlmd->dev.parent;
> - if (dev_is_pci(host))
> - pdev = to_pci_dev(host);
> - } else if (dev_is_pci(uport)) {
> - pdev = to_pci_dev(uport);
> - }
> -
> if (!pdev)
> return;
>
> @@ -591,14 +578,14 @@ void read_cdat_data(struct cxl_port *port)
> CXL_DOE_PROTOCOL_TABLE_ACCESS);
> if (!doe_mb) {
> dev_dbg(dev, "No CDAT mailbox\n");
> - return;
> + goto out;
> }
>
> port->cdat_available = true;
>
> if (cxl_cdat_get_length(dev, doe_mb, &length)) {
> dev_dbg(dev, "No CDAT length\n");
> - return;
> + goto out;
> }
>
> /*
> @@ -625,11 +612,13 @@ void read_cdat_data(struct cxl_port *port)
> port->cdat.table = buf->data;
> port->cdat.length = length;
>
> - return;
> + goto out;
> err:
> /* Don't leave table data allocated on error */
> devm_kfree(dev, buf);
> dev_err(dev, "Failed to read/validate CDAT.\n");
> +out:
> + pci_dev_put(pdev);
> }
> EXPORT_SYMBOL_NS_GPL(read_cdat_data, "CXL");
>
> diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
> index 625e4aa427db..5dc2815d82d8 100644
> --- a/drivers/cxl/core/port.c
> +++ b/drivers/cxl/core/port.c
> @@ -34,6 +34,32 @@
> static DEFINE_IDA(cxl_port_ida);
> static DEFINE_XARRAY(cxl_root_buses);
>
> +/**
> + * cxl_port_get_uport_pci_dev - get the PCI device for a port's upstream device
> + * @port: CXL port to map to a PCI device
> + *
> + * Return: A referenced PCI device, or NULL if the upstream device is not PCI.
> + * The caller must release the returned reference with pci_dev_put().
> + */
> +struct pci_dev *cxl_port_get_uport_pci_dev(struct cxl_port *port)
> +{
> + struct device *uport = port->uport_dev;
> + struct device *host;
> +
> + if (is_cxl_memdev(uport)) {
> + struct cxl_memdev *cxlmd = to_cxl_memdev(uport);
> +
> + host = cxlmd->dev.parent;
> + } else {
> + host = uport;
> + }
> +
> + if (!host || !dev_is_pci(host))
> + return NULL;
> +
> + return pci_dev_get(to_pci_dev(host));
> +}
> +
> /*
> * The terminal device in PCI is NULL and @platform_bus
> * for platform devices (for cxl_test)