From: Robert Richter <rrichter@amd.com>
To: Alison Schofield <alison.schofield@intel.com>
Cc: Davidlohr Bueso <dave@stgolabs.net>,
Jonathan Cameron <jic23@kernel.org>,
Dave Jiang <dave.jiang@intel.com>,
Vishal Verma <vishal.l.verma@intel.com>,
Ira Weiny <iweiny@kernel.org>, Li Ming <ming.li@zohomail.com>,
linux-cxl@vger.kernel.org
Subject: Re: [PATCH v3 3/9] cxl/region: Derive port granularity from selector bits
Date: Tue, 18 Aug 2026 12:01:11 +0200 [thread overview]
Message-ID: <aoQtZwK7_cvtl4fR@rric.localdomain> (raw)
In-Reply-To: <efef416440a89a44dfddb13ef390285a98c69cd4.1785444498.git.alison.schofield@intel.com>
On 30.07.26 15:20:23, Alison Schofield wrote:
> A user-created region currently derives each port decoder granularity
> from the parent granularity and ways. That recurrence assumes the
> selector bits follow the existing same-granularity ordering and cannot
> derive the decoder settings for a mixed-granularity region.
>
> Add cxl_region_is_mixed_gran() as the common predicate for regions
> whose granularity is finer than an interleaving root decoder.
>
> Update derive_port_granularity() to choose each port decoder's
> granularity from the selector bits not already used by its ancestors.
> For auto regions, compare the firmware-programmed granularity with the
> derived value and reject a mismatch.
The only requirement I see here is that firmware programmed selector
bits must be within the endpoint's bit mask (which matches the
region's total ways and gran configuration). The selector and
granularity of a single decoder within the chain may vary, as long as
it is within the total selector and does not overlap with other
decoders. It is not possible to calculate a single correct granularity
value for auto-mode. And in user-mode there are muliple setups and
values possible too, unless there are strict assignment rules given
that only allow a single subset.
>
> Originally-by: Robert Richter <rrichter@amd.com>
> Signed-off-by: Alison Schofield <alison.schofield@intel.com>
> ---
> drivers/cxl/core/region.c | 90 ++++++++++++++++++++++++++++++++++-----
> 1 file changed, 79 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
> index b0061f03892a..871dedd37cc8 100644
> --- a/drivers/cxl/core/region.c
> +++ b/drivers/cxl/core/region.c
> @@ -1552,32 +1552,94 @@ static bool region_selectors_fit(struct cxl_port *port,
> return true;
> }
>
> +/**
> + * cxl_region_is_mixed_gran() - Test for a mixed-granularity region
> + * @cxlr: region
> + *
> + * A region is mixed-granularity when an interleaving root decoder uses a
> + * larger granularity than the region.
> + *
> + * Return: true for a mixed-granularity region.
> + */
> +static inline bool cxl_region_is_mixed_gran(struct cxl_region *cxlr)
> +{
> + struct cxl_decoder *cxld = &cxlr->cxlrd->cxlsd.cxld;
> +
> + return cxld->interleave_ways > 1 &&
> + cxld->interleave_granularity > cxlr->params.interleave_granularity;
> +}
> +
> /**
> * derive_port_granularity() - Calculate the granularity for a port decoder
> + * @port: port being configured
> * @cxlr: region under construction
> + * @accum: selectors used by the ancestor decoders
> * @fanout: product of the ancestor switch ways
> - * @ig: filled with the port decoder granularity
> + * @iw: port decoder interleave ways
> + * @ig: filled with the derived granularity
> *
> - * Preserve the existing parent-granularity times parent-ways recurrence in
> - * terms of the region granularity and the fan-out above this port.
> + * Select the decoder granularity from the region selector bits not already
> + * used by its ancestors. Same-granularity regions allocate the lowest
> + * available selector bits first. Mixed-granularity regions allocate the
> + * highest available selector bits first so decoder granularities decrease
> + * from the root toward the endpoints.
> *
> - * Return: 0 on success.
> + * A passthrough decoder uses no selector bits and retains the granularity
> + * implied by the ancestor fan-out.
> + *
> + * Return: 0 on success, -ENXIO when no valid selector remains.
> */
> -static int derive_port_granularity(struct cxl_region *cxlr, int fanout,
> - int *ig)
> +static int derive_port_granularity(struct cxl_port *port,
> + struct cxl_region *cxlr, u64 accum,
> + int fanout, int iw, int *ig)
This function interface gets really out of control now. You need 5
args to calc the granularity and return 2 values? Something is wrong
here.
I guess we need to change the approach here. Maybe split target setup
for auto- and user-mode. We must simplify the code, I think that is
possible.
Will take a look.
-Robert
> {
> struct cxl_root_decoder *cxlrd = cxlr->cxlrd;
> int root_iw = cxlrd->cxlsd.cxld.interleave_ways;
> struct cxl_region_params *p = &cxlr->params;
> + u64 selector;
> int sel_distance;
>
> - sel_distance = is_power_of_2(root_iw) ? root_iw : root_iw / 3;
> - sel_distance *= fanout;
> - *ig = p->interleave_granularity * sel_distance;
> + selector = get_selector(p->interleave_ways,
> + p->interleave_granularity) & ~accum;
> +
> + if (iw == 1) {
> + sel_distance = is_power_of_2(root_iw) ? root_iw : root_iw / 3;
> + sel_distance *= fanout;
> + *ig = p->interleave_granularity * sel_distance;
> + } else if (selector && cxl_region_is_mixed_gran(cxlr)) {
> + *ig = (1ULL << fls64(selector)) / iw;
> + } else if (selector) {
> + *ig = 1ULL << __ffs64(selector);
> + } else {
> + dev_dbg(&cxlr->dev,
> + "%s:%s: no selector bits available for iw %d\n",
> + dev_name(port->uport_dev), dev_name(&port->dev), iw);
> + return -ENXIO;
> + }
> +
> + if (iw > 1 && (~selector & get_selector(iw, *ig))) {
> + dev_dbg(&cxlr->dev,
> + "%s:%s: derived selector %#llx exceeds remaining %#llx (iw %d ig %d)\n",
> + dev_name(port->uport_dev), dev_name(&port->dev),
> + get_selector(iw, *ig), selector, iw, *ig);
> + return -ENXIO;
> + }
>
> return 0;
> }
>
> +/**
> + * cxl_port_setup_targets() - Validate and program a port decoder
> + * @port: port being configured
> + * @cxlr: region under construction
> + * @cxled: endpoint decoder being attached
> + *
> + * Validate the decoder's selector placement and derive its interleave
> + * geometry. User-created regions program the derived values; auto regions
> + * validate the firmware-programmed values.
> + *
> + * Return: 0 on success, negative errno on invalid interleave geometry.
> + */
> static int cxl_port_setup_targets(struct cxl_port *port,
> struct cxl_region *cxlr,
> struct cxl_endpoint_decoder *cxled)
> @@ -1635,7 +1697,7 @@ static int cxl_port_setup_targets(struct cxl_port *port,
> goto add_target;
> }
>
> - rc = derive_port_granularity(cxlr, fanout, &ig);
> + rc = derive_port_granularity(port, cxlr, accum, fanout, iw, &ig);
> if (rc)
> return rc;
>
> @@ -1650,8 +1712,14 @@ static int cxl_port_setup_targets(struct cxl_port *port,
> }
>
> if (test_bit(CXL_REGION_F_AUTO, &cxlr->flags)) {
> + if (iw > 1 && cxld->interleave_granularity != ig) {
> + dev_dbg(&cxlr->dev,
> + "%s:%s: firmware ig %d != derived ig %d (iw %d)\n",
> + dev_name(port->uport_dev), dev_name(&port->dev),
> + cxld->interleave_granularity, ig, iw);
> + return -ENXIO;
> + }
> if (cxld->interleave_ways != iw ||
> - (iw > 1 && cxld->interleave_granularity != ig) ||
> !spa_maps_hpa(p, &cxld->hpa_range) ||
> ((cxld->flags & CXL_DECODER_F_ENABLE) == 0)) {
> dev_err(&cxlr->dev,
> --
> 2.37.3
>
next prev parent reply other threads:[~2026-08-18 10:01 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-30 22:20 [PATCH v3 0/9] cxl: Support mixed-granularity region interleaves Alison Schofield
2026-07-30 22:20 ` [PATCH v3 1/9] cxl/region: Factor port target calculations Alison Schofield
2026-07-30 22:36 ` sashiko-bot
2026-08-18 8:20 ` Robert Richter
2026-08-20 21:58 ` Alison Schofield
2026-07-30 22:20 ` [PATCH v3 2/9] cxl/region: Validate interleave selector bits Alison Schofield
2026-08-18 9:13 ` Robert Richter
2026-08-20 22:14 ` Alison Schofield
2026-07-30 22:20 ` [PATCH v3 3/9] cxl/region: Derive port granularity from " Alison Schofield
2026-08-18 10:01 ` Robert Richter [this message]
2026-08-20 22:48 ` Alison Schofield
2026-07-30 22:20 ` [PATCH v3 4/9] cxl/region: Account for mixed-granularity in position calculations Alison Schofield
2026-07-30 22:20 ` [PATCH v3 5/9] cxl/region: Allow mixed-granularity regions Alison Schofield
2026-07-30 22:20 ` [PATCH v3 6/9] cxl/region: Enforce coarse-to-fine ordering for " Alison Schofield
2026-07-30 22:20 ` [PATCH v3 7/9] cxl/region: Fail region creation on position check mismatch Alison Schofield
2026-07-30 22:40 ` sashiko-bot
2026-07-30 22:20 ` [PATCH v3 8/9] cxl/test: Add a topology to test mixed-granularity regions Alison Schofield
2026-07-30 22:20 ` [PATCH v3 9/9] Documentation/cxl: Describe multi-level interleave validation Alison Schofield
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aoQtZwK7_cvtl4fR@rric.localdomain \
--to=rrichter@amd.com \
--cc=alison.schofield@intel.com \
--cc=dave.jiang@intel.com \
--cc=dave@stgolabs.net \
--cc=iweiny@kernel.org \
--cc=jic23@kernel.org \
--cc=linux-cxl@vger.kernel.org \
--cc=ming.li@zohomail.com \
--cc=vishal.l.verma@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.