Re: [PATCH v24 06/11] cxl/hdm: Add support for getting region from committed decoder

Dave Jiang
2026-03-24T17:34:20Z

On 3/23/26 4:31 AM, alejandro.lucero-palau@amd.com wrote:
> From: Alejandro Lucero <alucerop@amd.com>
>

Maybe subject should be "Add helper function to retrieve a committed decoder and its region"?

> A Type2 device configured by the BIOS can already have its HDM
> committed. Add a cxl_get_committed_decoder() function for cheking
> so after memdev creation. A CXL region should have been created

Sentence doesn't quite make sense to me.

> during memdev initialization, therefore a Type2 driver can ask for
> such a region for working with the HPA. If the HDM is not committed,
> a Type2 driver will create the region after obtaining proper HPA
> and DPA space.
>
> Signed-off-by: Alejandro Lucero <alucerop@amd.com>
> ---
> drivers/cxl/core/hdm.c | 39 +++++++++++++++++++++++++++++++++++++++
> include/cxl/cxl.h | 3 +++
> 2 files changed, 42 insertions(+)
>
> diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
> index c222e98ae736..006be88efaa5 100644
> --- a/drivers/cxl/core/hdm.c
> +++ b/drivers/cxl/core/hdm.c
> @@ -686,6 +686,45 @@ int cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, u64 size)
> return devm_add_action_or_reset(&port->dev, cxl_dpa_release, cxled);
> }
>
> +static int find_committed_endpoint_decoder(struct device *dev, const void *data)
> +{
> + struct cxl_endpoint_decoder *cxled;
> + struct cxl_port *port;
> +
> + if (!is_endpoint_decoder(dev))
> + return 0;
> +
> + cxled = to_cxl_endpoint_decoder(dev);
> + port = cxled_to_port(cxled);
> +
> + return cxled->cxld.id == port->hdm_end;
> +}
> +
> +struct cxl_endpoint_decoder *cxl_get_committed_decoder(struct cxl_memdev *cxlmd,
> + struct cxl_region **cxlr)

kdoc header for this exported function?

> +{
> + struct cxl_port *endpoint = cxlmd->endpoint;
> + struct cxl_endpoint_decoder *cxled;
> + struct device *cxled_dev;
> +
> + if (!endpoint)
> + return NULL;
> +
> + guard(rwsem_read)(&cxl_rwsem.dpa);
> + cxled_dev = device_find_child(&endpoint->dev, NULL,
> + find_committed_endpoint_decoder);
> +
> + if (!cxled_dev)
> + return NULL;
> +
> + cxled = to_cxl_endpoint_decoder(cxled_dev);
> + *cxlr = cxled->cxld.region;

Should SFC take a ref on the region device?

> +
> + put_device(cxled_dev);

Maybe should let the caller release the reference? I think you will want to hold the reference by SFC until you no longer need the decoder?

DJ

> + return cxled;
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_get_committed_decoder, "CXL");
> +
> static void cxld_set_interleave(struct cxl_decoder *cxld, u32 *ctrl)
> {
> u16 eig;
> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
> index 10a9b8fa2f6b..2a61138e2a73 100644
> --- a/include/cxl/cxl.h
> +++ b/include/cxl/cxl.h
> @@ -231,4 +231,7 @@ struct cxl_dev_state *_devm_cxl_dev_state_create(struct device *dev,
> int cxl_set_capacity(struct cxl_dev_state *cxlds, u64 capacity);
> struct cxl_memdev *devm_cxl_add_memdev(struct cxl_dev_state *cxlds,
> const struct cxl_memdev_attach *attach);
> +struct cxl_region;
> +struct cxl_endpoint_decoder *cxl_get_committed_decoder(struct cxl_memdev *cxlmd,
> + struct cxl_region **cxlr);
> #endif /* __CXL_CXL_H__ */