From 868a8f1f045bce791c3123845075ee9a82a9fe4c Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Fri, 9 May 2025 17:06:55 +0200 Subject: [PATCH] cxl/region: Factor out code to find a root decoder's region In function cxl_add_to_region() there is code to determine a root decoder's region. Factor that code out. This is in preparation to further rework and simplify function cxl_add_to_region(). The reference count must be decremented after using the region. cxl_find_region_by_range() is paired with the put_cxl_region cleanup helper that can be used for this. [dj: Fixed up "obj __free(...) = NULL" pattern] Signed-off-by: Robert Richter Reviewed-by: Gregory Price Reviewed-by: Jonathan Cameron Reviewed-by: Dave Jiang Reviewed-by: Dan Williams Reviewed-by: Alison Schofield Reviewed-by: "Fabio M. De Francesco" Tested-by: Gregory Price Acked-by: Dan Williams Link: https://patch.msgid.link/20250509150700.2817697-11-rrichter@amd.com Signed-off-by: Dave Jiang --- drivers/cxl/core/region.c | 26 ++++++++++++++++---------- drivers/cxl/cxl.h | 1 + 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c index e76f1cf2e790..7def1c20b5f2 100644 --- a/drivers/cxl/core/region.c +++ b/drivers/cxl/core/region.c @@ -3405,12 +3405,23 @@ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd, return cxlr; } +static struct cxl_region * +cxl_find_region_by_range(struct cxl_root_decoder *cxlrd, struct range *hpa) +{ + struct device *region_dev; + + region_dev = device_find_child(&cxlrd->cxlsd.cxld.dev, hpa, + match_region_by_range); + if (!region_dev) + return NULL; + + return to_cxl_region(region_dev); +} + int cxl_add_to_region(struct cxl_endpoint_decoder *cxled) { struct range *hpa = &cxled->cxld.hpa_range; - struct device *region_dev; struct cxl_region_params *p; - struct cxl_region *cxlr; bool attach = false; int rc; @@ -3424,13 +3435,10 @@ int cxl_add_to_region(struct cxl_endpoint_decoder *cxled) * one does the construction and the others add to that. */ mutex_lock(&cxlrd->range_lock); - region_dev = device_find_child(&cxlrd->cxlsd.cxld.dev, hpa, - match_region_by_range); - if (!region_dev) { + struct cxl_region *cxlr __free(put_cxl_region) = + cxl_find_region_by_range(cxlrd, hpa); + if (!cxlr) cxlr = construct_region(cxlrd, cxled); - region_dev = &cxlr->dev; - } else - cxlr = to_cxl_region(region_dev); mutex_unlock(&cxlrd->range_lock); rc = PTR_ERR_OR_ZERO(cxlr); @@ -3455,8 +3463,6 @@ int cxl_add_to_region(struct cxl_endpoint_decoder *cxled) p->res); } - put_device(region_dev); - return rc; } EXPORT_SYMBOL_NS_GPL(cxl_add_to_region, "CXL"); diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h index 371f9dcfb61a..ba08b77b65da 100644 --- a/drivers/cxl/cxl.h +++ b/drivers/cxl/cxl.h @@ -741,6 +741,7 @@ struct cxl_root *find_cxl_root(struct cxl_port *port); DEFINE_FREE(put_cxl_root, struct cxl_root *, if (_T) put_device(&_T->port.dev)) DEFINE_FREE(put_cxl_port, struct cxl_port *, if (!IS_ERR_OR_NULL(_T)) put_device(&_T->dev)) DEFINE_FREE(put_cxl_root_decoder, struct cxl_root_decoder *, if (!IS_ERR_OR_NULL(_T)) put_device(&_T->cxlsd.cxld.dev)) +DEFINE_FREE(put_cxl_region, struct cxl_region *, if (!IS_ERR_OR_NULL(_T)) put_device(&_T->dev)) int devm_cxl_enumerate_ports(struct cxl_memdev *cxlmd); void cxl_bus_rescan(void); -- 2.25.1