From: Alison Schofield <alison.schofield@intel.com>
To: Davidlohr Bueso <dave@stgolabs.net>,
Jonathan Cameron <jic23@kernel.org>,
Dave Jiang <dave.jiang@intel.com>,
Alison Schofield <alison.schofield@intel.com>,
Vishal Verma <vishal.l.verma@intel.com>,
Ira Weiny <iweiny@kernel.org>, Li Ming <ming.li@zohomail.com>
Cc: linux-cxl@vger.kernel.org,
Sashiko AI Review <sashiko-bot@kernel.org>,
Richard Cheng <icheng@nvidia.com>
Subject: [PATCH v4 1/2] cxl/region: Allow regions with an unencodable passthrough granularity
Date: Thu, 3 Sep 2026 20:21:32 -0700 [thread overview]
Message-ID: <35566fc6397183a8be89055d1de9979eab9a24a5.1788487020.git.alison.schofield@intel.com> (raw)
In-Reply-To: <cover.1788487020.git.alison.schofield@intel.com>
Region creation fails when the interleave granularity accumulated below the
root decoder exceeds 16K, the maximum encodable in the HDM Decoder Control
IG field, even when the decoder that computes it does not interleave.
For example, a 2-way root decoder at 16K granularity with a single endpoint
below each host bridge. Neither host bridge decoder interleaves, yet the
32K granularity computed for them is rejected and the region fails to
attach an endpoint:
cxl region3: root0: invalid granularity calculation (16384 * 2)
cxl_port endpoint16: failed to attach decoder16.0 to region3: -22
A non-interleaving decoder does not consume the IG field, so region setup
is rejecting a value hardware never reads.
Only require the granularity to be encodable for interleaving decoders,
both where it is inherited from the parent and where it is computed for the
current decoder. Keep the computed value for passthrough decoders so it can
seed descendant decoder setup.
Accumulating the granularity below a passthrough decoder is not being
undone: a descendant that does interleave must see the accumulated value or
it would interleave on an address bit an ancestor already used. That
descendant inherits a granularity above 16K, so it is still rejected on its
own turn and a real overflow cannot be masked.
When committing a non-interleaving decoder, still program the granularity
if it is encodable; use a don't-care IG encoding only when it is not. This
preserves an encodable passthrough granularity across re-enumeration, so
descendants do not inherit a stale value.
As a consequence, the interleave_granularity attribute of a decoder whose
interleave_ways is 1 may report a value above 16K. Document that the
reported granularity for non-interleaving decoders is a don't-care value
that may exceed the maximum encodable in hardware.
Fixes: 18f35dc9314d ("cxl/region: Refactor granularity select in cxl_port_setup_targets()")
Reported-by: Sashiko AI Review <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260530002613.682E71F00893@smtp.kernel.org/
Assisted-by: Claude:Opus-4-8
Reviewed-by: Richard Cheng <icheng@nvidia.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Alison Schofield <alison.schofield@intel.com>
---
Documentation/ABI/testing/sysfs-bus-cxl | 5 +++-
drivers/cxl/core/hdm.c | 8 +++++-
drivers/cxl/core/region.c | 34 ++++++++++++++-----------
3 files changed, 30 insertions(+), 17 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-bus-cxl b/Documentation/ABI/testing/sysfs-bus-cxl
index 7352dbd70bc7..6abfd792f07e 100644
--- a/Documentation/ABI/testing/sysfs-bus-cxl
+++ b/Documentation/ABI/testing/sysfs-bus-cxl
@@ -412,7 +412,10 @@ Description:
space this decoder claims at address N before the decode rotates
to the next target in the interleave at address N +
interleave_granularity (assuming N is aligned to
- interleave_granularity).
+ interleave_granularity). When 'interleave_ways' is 1, the
+ decoder does not interleave and the reported granularity is
+ a don't-care value that may exceed the maximum encodable in
+ hardware.
What: /sys/bus/cxl/devices/decoderX.Y/create_pmem_region
diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
index 0c80b76a5f9b..5ff1a75124cc 100644
--- a/drivers/cxl/core/hdm.c
+++ b/drivers/cxl/core/hdm.c
@@ -691,7 +691,13 @@ static void cxld_set_interleave(struct cxl_decoder *cxld, u32 *ctrl)
if (WARN_ONCE(ways_to_eiw(cxld->interleave_ways, &eiw),
"invalid interleave_ways: %d\n", cxld->interleave_ways))
return;
- if (WARN_ONCE(granularity_to_eig(cxld->interleave_granularity, &eig),
+
+ /*
+ * A non-interleaving decoder ignores the IG field, so an unencodable
+ * granularity is a don't-care rather than a failure.
+ */
+ if (granularity_to_eig(cxld->interleave_granularity, &eig) &&
+ WARN_ONCE(cxld->interleave_ways > 1,
"invalid interleave_granularity: %d\n",
cxld->interleave_granularity))
return;
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index 27e63e6dab7c..89693f0181dd 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -1435,6 +1435,20 @@ static int check_interleave_cap(struct cxl_decoder *cxld, int iw, int ig)
return 0;
}
+/*
+ * Hardware only consults the IG field of a decoder that interleaves, so a
+ * granularity the field cannot encode only matters when @ways exceeds one.
+ */
+static bool granularity_is_valid(int ways, int granularity)
+{
+ u16 eig;
+
+ if (ways <= 1)
+ return true;
+
+ return granularity_to_eig(granularity, &eig) == 0;
+}
+
static int cxl_port_setup_targets(struct cxl_port *port,
struct cxl_region *cxlr,
struct cxl_endpoint_decoder *cxled)
@@ -1449,7 +1463,6 @@ 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;
- u16 eig, peig;
u8 eiw, peiw;
/*
@@ -1522,12 +1535,11 @@ static int cxl_port_setup_targets(struct cxl_port *port,
parent_iw = parent_cxld->interleave_ways;
}
- rc = granularity_to_eig(parent_ig, &peig);
- if (rc) {
+ if (!granularity_is_valid(parent_iw, parent_ig)) {
dev_dbg(&cxlr->dev, "%s:%s: invalid parent granularity: %d\n",
dev_name(parent_port->uport_dev),
dev_name(&parent_port->dev), parent_ig);
- return rc;
+ return -EINVAL;
}
rc = ways_to_eiw(parent_iw, &peiw);
@@ -1550,20 +1562,12 @@ static int cxl_port_setup_targets(struct cxl_port *port,
* Interleave granularity is a multiple of @parent_port granularity.
* Multiplier is the parent port interleave ways.
*/
- rc = granularity_to_eig(parent_ig * parent_iw, &eig);
- if (rc) {
+ ig = parent_ig * parent_iw;
+ if (!granularity_is_valid(iw, ig)) {
dev_dbg(&cxlr->dev,
"%s: invalid granularity calculation (%d * %d)\n",
dev_name(&parent_port->dev), parent_ig, parent_iw);
- return rc;
- }
-
- rc = eig_to_granularity(eig, &ig);
- if (rc) {
- dev_dbg(&cxlr->dev, "%s:%s: invalid interleave: %d\n",
- dev_name(port->uport_dev), dev_name(&port->dev),
- 256 << eig);
- return rc;
+ return -EINVAL;
}
if (iw > 8 || iw > cxlsd->nr_targets) {
--
2.37.3
next prev parent reply other threads:[~2026-09-04 3:21 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-04 3:21 [PATCH v4 0/2] cxl: Allow passthrough decoders with >16K granularity Alison Schofield
2026-09-04 3:21 ` Alison Schofield [this message]
2026-09-04 3:36 ` [PATCH v4 1/2] cxl/region: Allow regions with an unencodable passthrough granularity sashiko-bot
2026-09-04 3:53 ` Alison Schofield
2026-09-04 3:21 ` [PATCH v4 2/2] cxl/test: Add a 2-way 16K root decoder for passthrough testing 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=35566fc6397183a8be89055d1de9979eab9a24a5.1788487020.git.alison.schofield@intel.com \
--to=alison.schofield@intel.com \
--cc=dave.jiang@intel.com \
--cc=dave@stgolabs.net \
--cc=icheng@nvidia.com \
--cc=iweiny@kernel.org \
--cc=jic23@kernel.org \
--cc=linux-cxl@vger.kernel.org \
--cc=ming.li@zohomail.com \
--cc=sashiko-bot@kernel.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox