Skip to content

Commit 9466ee9

Browse files
Robert Richterdavejiang
authored andcommitted
cxl/region: Factor out code to find the root decoder
In function cxl_add_to_region() there is code to determine the root decoder associated to an endpoint decoder. Factor out that code for later reuse. This has the benefit of reducing cxl_add_to_region()'s function complexity. The reference count must be decremented after using the root decoder. cxl_find_root_decoder() is paired with the put_cxl_root_decoder cleanup helper that can be used for this. [dj: Fixed up "obj __free(...) = NULL" pattern] Signed-off-by: Robert Richter <rrichter@amd.com> Reviewed-by: Gregory Price <gourry@gourry.net> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Dan Williams <dan.j.williams@intel.com> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Reviewed-by: "Fabio M. De Francesco" <fabio.m.de.francesco@linux.intel.com> Tested-by: Gregory Price <gourry@gourry.net> Acked-by: Dan Williams <dan.j.williams@intel.com> Link: https://patch.msgid.link/20250509150700.2817697-10-rrichter@amd.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
1 parent 74bf125 commit 9466ee9

File tree

2 files changed

+30
-19
lines changed

2 files changed

+30
-19
lines changed

drivers/cxl/core/region.c

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3216,6 +3216,29 @@ static int match_root_decoder_by_range(struct device *dev,
32163216
return range_contains(r1, r2);
32173217
}
32183218

3219+
static struct cxl_root_decoder *
3220+
cxl_find_root_decoder(struct cxl_endpoint_decoder *cxled)
3221+
{
3222+
struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
3223+
struct cxl_port *port = cxled_to_port(cxled);
3224+
struct cxl_root *cxl_root __free(put_cxl_root) = find_cxl_root(port);
3225+
struct cxl_decoder *cxld = &cxled->cxld;
3226+
struct range *hpa = &cxld->hpa_range;
3227+
struct device *cxlrd_dev;
3228+
3229+
cxlrd_dev = device_find_child(&cxl_root->port.dev, hpa,
3230+
match_root_decoder_by_range);
3231+
if (!cxlrd_dev) {
3232+
dev_err(cxlmd->dev.parent,
3233+
"%s:%s no CXL window for range %#llx:%#llx\n",
3234+
dev_name(&cxlmd->dev), dev_name(&cxld->dev),
3235+
cxld->hpa_range.start, cxld->hpa_range.end);
3236+
return NULL;
3237+
}
3238+
3239+
return to_cxl_root_decoder(cxlrd_dev);
3240+
}
3241+
32193242
static int match_region_by_range(struct device *dev, const void *data)
32203243
{
32213244
struct cxl_region_params *p;
@@ -3384,29 +3407,17 @@ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
33843407

33853408
int cxl_add_to_region(struct cxl_endpoint_decoder *cxled)
33863409
{
3387-
struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
3388-
struct cxl_port *port = cxled_to_port(cxled);
3389-
struct cxl_root *cxl_root __free(put_cxl_root) = find_cxl_root(port);
33903410
struct range *hpa = &cxled->cxld.hpa_range;
3391-
struct cxl_decoder *cxld = &cxled->cxld;
3392-
struct device *cxlrd_dev, *region_dev;
3393-
struct cxl_root_decoder *cxlrd;
3411+
struct device *region_dev;
33943412
struct cxl_region_params *p;
33953413
struct cxl_region *cxlr;
33963414
bool attach = false;
33973415
int rc;
33983416

3399-
cxlrd_dev = device_find_child(&cxl_root->port.dev, &cxld->hpa_range,
3400-
match_root_decoder_by_range);
3401-
if (!cxlrd_dev) {
3402-
dev_err(cxlmd->dev.parent,
3403-
"%s:%s no CXL window for range %#llx:%#llx\n",
3404-
dev_name(&cxlmd->dev), dev_name(&cxld->dev),
3405-
cxld->hpa_range.start, cxld->hpa_range.end);
3417+
struct cxl_root_decoder *cxlrd __free(put_cxl_root_decoder) =
3418+
cxl_find_root_decoder(cxled);
3419+
if (!cxlrd)
34063420
return -ENXIO;
3407-
}
3408-
3409-
cxlrd = to_cxl_root_decoder(cxlrd_dev);
34103421

34113422
/*
34123423
* Ensure that if multiple threads race to construct_region() for @hpa
@@ -3424,7 +3435,7 @@ int cxl_add_to_region(struct cxl_endpoint_decoder *cxled)
34243435

34253436
rc = PTR_ERR_OR_ZERO(cxlr);
34263437
if (rc)
3427-
goto out;
3438+
return rc;
34283439

34293440
attach_target(cxlr, cxled, -1, TASK_UNINTERRUPTIBLE);
34303441

@@ -3445,8 +3456,7 @@ int cxl_add_to_region(struct cxl_endpoint_decoder *cxled)
34453456
}
34463457

34473458
put_device(region_dev);
3448-
out:
3449-
put_device(cxlrd_dev);
3459+
34503460
return rc;
34513461
}
34523462
EXPORT_SYMBOL_NS_GPL(cxl_add_to_region, "CXL");

drivers/cxl/cxl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,7 @@ struct cxl_root *find_cxl_root(struct cxl_port *port);
740740

741741
DEFINE_FREE(put_cxl_root, struct cxl_root *, if (_T) put_device(&_T->port.dev))
742742
DEFINE_FREE(put_cxl_port, struct cxl_port *, if (!IS_ERR_OR_NULL(_T)) put_device(&_T->dev))
743+
DEFINE_FREE(put_cxl_root_decoder, struct cxl_root_decoder *, if (!IS_ERR_OR_NULL(_T)) put_device(&_T->cxlsd.cxld.dev))
743744

744745
int devm_cxl_enumerate_ports(struct cxl_memdev *cxlmd);
745746
void cxl_bus_rescan(void);

0 commit comments

Comments
 (0)