cxl_region_determine_granularity() rejects any user-supplied granularity that does not exactly match the root decoder's granularity, making it impossible to create mixed-granularity regions from userspace even when the kernel driver accepts them.
Relax the check to allow region_gran <= root_gran. The kernel validates constraints at region-commit time so this function only needs to reject the one arrangement it can determine is always wrong: a region granularity greater than the root decoder's granularity. Update the cxl-create-region man page to document the new behavior. Signed-off-by: Alison Schofield <[email protected]> --- Documentation/cxl/cxl-create-region.txt | 13 ++++++++----- cxl/region.c | 13 +++++++------ 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/Documentation/cxl/cxl-create-region.txt b/Documentation/cxl/cxl-create-region.txt index b244af60b8a6..d2ff47ec2a18 100644 --- a/Documentation/cxl/cxl-create-region.txt +++ b/Documentation/cxl/cxl-create-region.txt @@ -93,11 +93,14 @@ include::bus-option.txt[] -g:: --granularity=:: - The interleave granularity for the new region. Must match the selected - root decoder's (if provided) granularity. If the root decoder is - interleaved across more than one host-bridge then this value must match - that granularity. Otherwise, for non-interleaved decode windows, any - granularity can be specified as long as all devices support that setting. + The interleave granularity for the new region. If the root decoder is + interleaved across more than one host bridge, the region granularity + must be less than or equal to the root decoder granularity. A region + granularity less than root creates a mixed-granularity configuration + where the root interleaves at a coarser granularity and subordinate + switches interleave at the finer region granularity. For + non-interleaved root decoders, any granularity can be specified as + long as all devices support that setting. -d:: --decoder=:: diff --git a/cxl/region.c b/cxl/region.c index 85d4d9bb54f2..fbc7272b9a84 100644 --- a/cxl/region.c +++ b/cxl/region.c @@ -632,15 +632,16 @@ static int cxl_region_determine_granularity(struct cxl_region *region, return p->granularity; /* - * For ways > 1, only allow the same granularity as the selected - * root decoder + * For ways > 1, allow any region granularity up to and including the + * root decoder granularity. A finer region granularity produces a + * mixed-granularity configuration and a coarser one is always invalid. */ - if (p->granularity == granularity) - return granularity; + if (p->granularity <= granularity) + return p->granularity; log_err(&rl, - "%s: For an x%d root, only root decoder granularity (%d) permitted\n", - devname, ways, granularity); + "%s: region granularity (%d) cannot exceed root decoder granularity (%d)\n", + devname, p->granularity, granularity); return -EINVAL; } base-commit: bbd403a03fa2a1551c1a10bbf78f32027c718758 -- 2.37.3
