Re: [PATCH v7 08/17] cxl/pci: Map CXL PCIe Upstream Switch Port RAS registers

Dave Jiang
2025-02-11T23:02:33Z

On 2/11/25 12:24 PM, Terry Bowman wrote:
> Add logic to map CXL PCIe Upstream Switch Port (USP) RAS registers.
>
> Introduce 'struct cxl_regs' member into 'struct cxl_port' to cache a
> pointer to the CXL Upstream Port's mapped RAS registers.
>
> Also, introduce cxl_uport_init_ras_reporting() to perform the USP RAS
> register mapping. This is similar to the existing
> cxl_dport_init_ras_reporting() but for USP devices.
>
> The USP may have multiple downstream endpoints. Before mapping RAS
> registers check if the registers are already mapped.
>
> Introduce a mutex for synchronizing accesses to the cached RAS
> mapping.

s/Introduce a mutex/Use the ras_init_mutex/ since it was introduced in the previous patch.
>
> Signed-off-by: Terry Bowman <terry.bowman@amd.com>
> Reviewed-by: Gregory Price <gourry@gourry.net>

Just a minor comment below
Reviewed-by: Dave Jiang <dave.jiang@intel.com>

> ---
> drivers/cxl/core/pci.c | 19 ++++++++++++++++++-
> drivers/cxl/cxl.h | 4 ++++
> drivers/cxl/mem.c | 8 ++++++++
> 3 files changed, 30 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
> index 143c853a52c4..25513b9a8aff 100644
> --- a/drivers/cxl/core/pci.c
> +++ b/drivers/cxl/core/pci.c
> @@ -775,6 +775,24 @@ static void cxl_disable_rch_root_ints(struct cxl_dport *dport)
> writel(aer_cmd, aer_base + PCI_ERR_ROOT_COMMAND);
> }
>
> +void cxl_uport_init_ras_reporting(struct cxl_port *port)
> +{
> +
> + /* uport may have more than 1 downstream EP. Check if already mapped. */
> + mutex_lock(&ras_init_mutex);

You can use guard() here.

> + if (port->uport_regs.ras) {
> + mutex_unlock(&ras_init_mutex);
> + return;
> + }
> +
> + port->reg_map.host = &port->dev;
> + if (cxl_map_component_regs(&port->reg_map, &port->uport_regs,
> + BIT(CXL_CM_CAP_CAP_ID_RAS)))
> + dev_err(&port->dev, "Failed to map RAS capability\n");
> + mutex_unlock(&ras_init_mutex);
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_uport_init_ras_reporting, "CXL");
> +
> /**
> * cxl_dport_init_ras_reporting - Setup CXL RAS report on this dport
> * @dport: the cxl_dport that needs to be initialized
> @@ -801,7 +819,6 @@ void cxl_dport_init_ras_reporting(struct cxl_dport *dport)
> BIT(CXL_CM_CAP_CAP_ID_RAS)))
> dev_err(dport_dev, "Failed to map RAS capability\n");
> mutex_unlock(&ras_init_mutex);
> -
> }
> EXPORT_SYMBOL_NS_GPL(cxl_dport_init_ras_reporting, "CXL");
>
> diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
> index 82d0a8555a11..49f29a3ef68e 100644
> --- a/drivers/cxl/cxl.h
> +++ b/drivers/cxl/cxl.h
> @@ -581,6 +581,7 @@ struct cxl_dax_region {
> * @parent_dport: dport that points to this port in the parent
> * @decoder_ida: allocator for decoder ids
> * @reg_map: component and ras register mapping parameters
> + * @uport_regs: mapped component registers
> * @nr_dports: number of entries in @dports
> * @hdm_end: track last allocated HDM decoder instance for allocation ordering
> * @commit_end: cursor to track highest committed decoder for commit ordering
> @@ -602,6 +603,7 @@ struct cxl_port {
> struct cxl_dport *parent_dport;
> struct ida decoder_ida;
> struct cxl_register_map reg_map;
> + struct cxl_component_regs uport_regs;
> int nr_dports;
> int hdm_end;
> int commit_end;
> @@ -755,8 +757,10 @@ struct cxl_dport *devm_cxl_add_rch_dport(struct cxl_port *port,
>
> #ifdef CONFIG_PCIEAER_CXL
> void cxl_dport_init_ras_reporting(struct cxl_dport *dport);
> +void cxl_uport_init_ras_reporting(struct cxl_port *port);
> #else
> static inline void cxl_dport_init_ras_reporting(struct cxl_dport *dport) { }
> +static inline void cxl_uport_init_ras_reporting(struct cxl_port *port) { }
> #endif
>
> struct cxl_decoder *to_cxl_decoder(struct device *dev);
> diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c
> index 8c1144bbc058..541cabca434e 100644
> --- a/drivers/cxl/mem.c
> +++ b/drivers/cxl/mem.c
> @@ -60,6 +60,7 @@ static bool dev_is_cxl_pci(struct device *dev, u32 pcie_type)
> static void cxl_init_ep_ports_aer(struct cxl_ep *ep)
> {
> struct cxl_dport *dport = ep->dport;
> + struct cxl_port *port = ep->next;
>
> if (dport) {
> struct device *dport_dev = dport->dport_dev;
> @@ -68,6 +69,13 @@ static void cxl_init_ep_ports_aer(struct cxl_ep *ep)
> dev_is_cxl_pci(dport_dev, PCI_EXP_TYPE_ROOT_PORT))
> cxl_dport_init_ras_reporting(dport);
> }
> +
> + if (port) {
> + struct device *uport_dev = port->uport_dev;
> +
> + if (dev_is_cxl_pci(uport_dev, PCI_EXP_TYPE_UPSTREAM))
> + cxl_uport_init_ras_reporting(port);
> + }
> }
>
> static int devm_cxl_add_endpoint(struct device *host, struct cxl_memdev *cxlmd,