Re: [PATCH v2 06/15] cxl/region: Use endpoint's HPA range to find the port's decoder

Gregory Price
2025-04-24T00:28:07Z

On Tue, Feb 18, 2025 at 02:23:47PM +0100, Robert Richter wrote:
> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
> index d898c9f51113..5048511f9de5 100644
> --- a/drivers/cxl/core/region.c
> +++ b/drivers/cxl/core/region.c
> @@ -906,7 +905,7 @@ cxl_find_decoder_early(struct cxl_port *port,
> return &cxled->cxld;
>
> if (test_bit(CXL_REGION_F_AUTO, &cxlr->flags))
> - dev = device_find_child(&port->dev, &cxlr->params,
> + dev = device_find_child(&port->dev, &cxled->cxld.hpa_range,
> match_auto_decoder);

This semantic has now changed because of the linear caching set.

Working around this with something like this hack for now

Probably we want to pull the range out of the resource and put it right
in the params instead of the local variable, but just getting it working
for testing for now

~Gregory

---

diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index eac873125e6d..c8d38ce55045 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -833,7 +833,8 @@ static int match_free_decoder(struct device *dev, const void *data)
}

static bool region_res_match_cxl_range(const struct cxl_region_params *p,
- struct range *range)
+ const struct range *range1,
+ const struct range *range2)
{
if (!p->res)
return false;
@@ -843,8 +844,8 @@ static bool region_res_match_cxl_range(const struct cxl_region_params *p,
* to be fronted by the DRAM range in current known implementation.
* This assumption will be made until a variant implementation exists.
*/
- return p->res->start + p->cache_size == range->start &&
- p->res->end == range->end;
+ return range1->start + p->cache_size == range2->start &&
+ range1->end == range2->end;
}

static int cxl_port_calc_hpa(struct cxl_port *port, struct cxl_decoder *cxld,
@@ -885,11 +886,15 @@ static int cxl_port_calc_hpa(struct cxl_port *port, struct cxl_decoder *cxld,
return 1;
}

+struct mad_context {
+ struct cxl_region_params *p;
+ struct range *r;
+};
static int match_auto_decoder(struct device *dev, const void *data)
{
- const struct cxl_region_params *p = data;
+ const struct range *r;
struct cxl_decoder *cxld;
- struct range *r;
+ const struct mad_context *ctx = data;

if (!is_switch_decoder(dev))
return 0;
@@ -897,7 +902,7 @@ static int match_auto_decoder(struct device *dev, const void *data)
cxld = to_cxl_decoder(dev);
r = &cxld->hpa_range;

- if (region_res_match_cxl_range(p, r))
+ if (region_res_match_cxl_range(ctx->p, ctx->r, r))
return 1;

return 0;
@@ -916,13 +921,14 @@ cxl_find_decoder_early(struct cxl_port *port,
struct cxl_region *cxlr)
{
struct device *dev;
+ struct mad_context mad = { .p = &cxlr->params,
+ .r =&cxled->cxld.hpa_range };

if (port == cxled_to_port(cxled))
return &cxled->cxld;

if (test_bit(CXL_REGION_F_AUTO, &cxlr->flags))
- dev = device_find_child(&port->dev, &cxlr->params,
- match_auto_decoder);
+ dev = device_find_child(&port->dev, &mad, match_auto_decoder);
else
dev = device_find_child(&port->dev, NULL, match_free_decoder);
if (!dev)
@@ -1363,6 +1369,7 @@ static int cxl_port_setup_targets(struct cxl_port *port,
struct cxl_decoder *cxld = cxl_rr->decoder;
struct cxl_switch_decoder *cxlsd;
struct cxl_port *iter = port;
+ struct range r;
u16 eig, peig;
u8 eiw, peiw;

@@ -1488,10 +1495,12 @@ static int cxl_port_setup_targets(struct cxl_port *port,
return -ENXIO;
}

+ r.start = p ? p->res->start : 0;
+ r.end = p ? p->res->end : 0;
if (test_bit(CXL_REGION_F_AUTO, &cxlr->flags)) {
if (cxld->interleave_ways != iw ||
cxld->interleave_granularity != ig ||
- !region_res_match_cxl_range(p, &cxld->hpa_range) ||
+ !region_res_match_cxl_range(p, &r, &cxld->hpa_range) ||
((cxld->flags & CXL_DECODER_F_ENABLE) == 0)) {
dev_err(&cxlr->dev,
"%s:%s %s expected iw: %d ig: %d %pr\n",