* [ndctl PATCH 1/3] test/cxl-create-region.sh: fold in XOR region coverage
2026-06-11 0:19 [ndctl PATCH 0/3] Add CXL region passthrough >16K gran test Alison Schofield
@ 2026-06-11 0:19 ` Alison Schofield
2026-06-11 0:19 ` [ndctl PATCH 2/3] test/cxl-create-region.sh: deduplicate decoder and memdev lookups Alison Schofield
2026-06-11 0:19 ` [ndctl PATCH 3/3] test/cxl-create-region.sh: add passthrough >16K granularity test case Alison Schofield
2 siblings, 0 replies; 4+ messages in thread
From: Alison Schofield @ 2026-06-11 0:19 UTC (permalink / raw)
To: nvdimm, linux-cxl; +Cc: Alison Schofield
In the CXL Unit Test Suite, region creation coverage is split between
cxl-create-region.sh and cxl-xor-region.sh.
Consolidate the XOR coverage into cxl-create-region.sh so region
creation testing lives in one place. This avoids maintaining parallel
test infrastructure and makes it easier to add new region creation
cases.
Remove the now redundant cxl-xor-region.sh.
Continue to maintain cxl-region-sysfs.sh because it exercises the CXL
driver ABI directly.
Assisted-by: Claude:Opus-4-8
Signed-off-by: Alison Schofield <alison.schofield@intel.com>
---
test/cxl-create-region.sh | 111 ++++++++++++++++++++++++++++++++
test/cxl-xor-region.sh | 129 --------------------------------------
test/meson.build | 2 -
3 files changed, 111 insertions(+), 131 deletions(-)
delete mode 100644 test/cxl-xor-region.sh
diff --git a/test/cxl-create-region.sh b/test/cxl-create-region.sh
index 658b9b8ff58a..d7a6840fed1a 100644
--- a/test/cxl-create-region.sh
+++ b/test/cxl-create-region.sh
@@ -133,6 +133,98 @@ create_single()
destroy_regions "$region"
}
+create_and_destroy_region()
+{
+ region=$($CXL create-region -d "$decoder" -m "$memdevs" |
+ jq -r ".region")
+
+ if [[ ! $region ]]; then
+ echo "create-region failed for $decoder"
+ err "$LINENO"
+ fi
+
+ destroy_regions "$region"
+}
+
+setup_x1()
+{
+ # Find an x1 decoder
+ decoder=$($CXL list -b cxl_test -D -d root | jq -r ".[] |
+ select(.pmem_capable == true) |
+ select(.nr_targets == 1) |
+ .decoder")
+
+ # Find a memdev for this host-bridge
+ port_dev0=$($CXL list -T -d "$decoder" | jq -r ".[] |
+ .targets | .[] | select(.position == 0) | .target")
+ mem0=$($CXL list -M -p "$port_dev0" | jq -r ".[0].memdev")
+ memdevs="$mem0"
+}
+
+setup_x2()
+{
+ # Find an x2 decoder
+ decoder=$($CXL list -b cxl_test -D -d root | jq -r ".[] |
+ select(.pmem_capable == true) |
+ select(.nr_targets == 2) |
+ .decoder")
+
+ # Find a memdev for each host-bridge interleave position
+ port_dev0=$($CXL list -T -d "$decoder" | jq -r ".[] |
+ .targets | .[] | select(.position == 0) | .target")
+ port_dev1=$($CXL list -T -d "$decoder" | jq -r ".[] |
+ .targets | .[] | select(.position == 1) | .target")
+ mem0=$($CXL list -M -p "$port_dev0" | jq -r ".[0].memdev")
+ mem1=$($CXL list -M -p "$port_dev1" | jq -r ".[0].memdev")
+ memdevs="$mem0 $mem1"
+}
+
+setup_x4()
+{
+ # find an x2 decoder
+ decoder=$($CXL list -b cxl_test -D -d root | jq -r ".[] |
+ select(.pmem_capable == true) |
+ select(.nr_targets == 2) |
+ .decoder")
+
+ # Find a memdev for each host-bridge interleave position
+ port_dev0=$($CXL list -T -d "$decoder" | jq -r ".[] |
+ .targets | .[] | select(.position == 0) | .target")
+ port_dev1=$($CXL list -T -d "$decoder" | jq -r ".[] |
+ .targets | .[] | select(.position == 1) | .target")
+ mem0=$($CXL list -M -p "$port_dev0" | jq -r ".[0].memdev")
+ mem1=$($CXL list -M -p "$port_dev1" | jq -r ".[0].memdev")
+ mem2=$($CXL list -M -p "$port_dev0" | jq -r ".[1].memdev")
+ mem3=$($CXL list -M -p "$port_dev1" | jq -r ".[1].memdev")
+ memdevs="$mem0 $mem1 $mem2 $mem3"
+}
+
+setup_x3()
+{
+ # find an x3 decoder
+ decoder=$($CXL list -b cxl_test -D -d root | jq -r ".[] |
+ select(.pmem_capable == true) |
+ select(.nr_targets == 3) |
+ .decoder")
+
+ if [[ ! $decoder ]]; then
+ echo "no x3 decoder found, skipping xor-x3 test"
+ return
+ fi
+
+ # Find a memdev for each host-bridge interleave position
+ port_dev0=$($CXL list -T -d "$decoder" | jq -r ".[] |
+ .targets | .[] | select(.position == 0) | .target")
+ port_dev1=$($CXL list -T -d "$decoder" | jq -r ".[] |
+ .targets | .[] | select(.position == 1) | .target")
+ port_dev2=$($CXL list -T -d "$decoder" | jq -r ".[] |
+ .targets | .[] | select(.position == 2) | .target")
+ mem0=$($CXL list -M -p "$port_dev0" | jq -r ".[0].memdev")
+ mem1=$($CXL list -M -p "$port_dev1" | jq -r ".[0].memdev")
+ mem2=$($CXL list -M -p "$port_dev2" | jq -r ".[0].memdev")
+ memdevs="$mem0 $mem1 $mem2"
+}
+
# test region creation on devices behind a single-port host-bridge
create_single
@@ -149,6 +241,25 @@ for mem in ${mems[@]}; do
create_subregions "$mem"
done
+# Reload cxl_test with XOR interleave arithmetic to exercise the XOR math
+# option of the CXL driver. Create x1,2,3,4 regions across the XOR roots.
+# As with the modulo tests above, changes to the CXL topology in
+# tools/testing/cxl/test/cxl.c may require an update here.
+modprobe -r cxl_test
+modprobe cxl_test interleave_arithmetic=1
+
+setup_x1
+create_and_destroy_region
+setup_x2
+create_and_destroy_region
+setup_x4
+create_and_destroy_region
+# x3 decoder may not be available in cxl/test topo yet
+setup_x3
+if [[ $decoder ]]; then
+ create_and_destroy_region
+fi
+
check_dmesg "$LINENO"
modprobe -r cxl_test
diff --git a/test/cxl-xor-region.sh b/test/cxl-xor-region.sh
deleted file mode 100644
index fb4f9a0a1515..000000000000
--- a/test/cxl-xor-region.sh
+++ /dev/null
@@ -1,129 +0,0 @@
-#!/bin/bash
-# SPDX-License-Identifier: GPL-2.0
-# Copyright (C) 2022 Intel Corporation. All rights reserved.
-
-. $(dirname $0)/common
-
-rc=77
-
-set -ex
-
-trap 'err $LINENO' ERR
-
-check_prereq "jq"
-
-modprobe -r cxl_test
-modprobe cxl_test interleave_arithmetic=1
-rc=1
-
-# THEORY OF OPERATION: Create x1,2,3,4 regions to exercise the XOR math
-# option of the CXL driver. As with other cxl_test tests, changes to the
-# CXL topology in tools/testing/cxl/test/cxl.c may require an update here.
-
-create_and_destroy_region()
-{
- region=$($CXL create-region -d "$decoder" -m "$memdevs" |
- jq -r ".region")
-
- if [[ ! $region ]]; then
- echo "create-region failed for $decoder"
- err "$LINENO"
- fi
-
- $CXL destroy-region -f -b cxl_test "$region"
-}
-
-setup_x1()
-{
- # Find an x1 decoder
- decoder=$($CXL list -b cxl_test -D -d root | jq -r ".[] |
- select(.pmem_capable == true) |
- select(.nr_targets == 1) |
- .decoder")
-
- # Find a memdev for this host-bridge
- port_dev0=$($CXL list -T -d "$decoder" | jq -r ".[] |
- .targets | .[] | select(.position == 0) | .target")
- mem0=$($CXL list -M -p "$port_dev0" | jq -r ".[0].memdev")
- memdevs="$mem0"
-}
-
-setup_x2()
-{
- # Find an x2 decoder
- decoder=$($CXL list -b cxl_test -D -d root | jq -r ".[] |
- select(.pmem_capable == true) |
- select(.nr_targets == 2) |
- .decoder")
-
- # Find a memdev for each host-bridge interleave position
- port_dev0=$($CXL list -T -d "$decoder" | jq -r ".[] |
- .targets | .[] | select(.position == 0) | .target")
- port_dev1=$($CXL list -T -d "$decoder" | jq -r ".[] |
- .targets | .[] | select(.position == 1) | .target")
- mem0=$($CXL list -M -p "$port_dev0" | jq -r ".[0].memdev")
- mem1=$($CXL list -M -p "$port_dev1" | jq -r ".[0].memdev")
- memdevs="$mem0 $mem1"
-}
-
-setup_x4()
-{
- # find an x2 decoder
- decoder=$($CXL list -b cxl_test -D -d root | jq -r ".[] |
- select(.pmem_capable == true) |
- select(.nr_targets == 2) |
- .decoder")
-
- # Find a memdev for each host-bridge interleave position
- port_dev0=$($CXL list -T -d "$decoder" | jq -r ".[] |
- .targets | .[] | select(.position == 0) | .target")
- port_dev1=$($CXL list -T -d "$decoder" | jq -r ".[] |
- .targets | .[] | select(.position == 1) | .target")
- mem0=$($CXL list -M -p "$port_dev0" | jq -r ".[0].memdev")
- mem1=$($CXL list -M -p "$port_dev1" | jq -r ".[0].memdev")
- mem2=$($CXL list -M -p "$port_dev0" | jq -r ".[1].memdev")
- mem3=$($CXL list -M -p "$port_dev1" | jq -r ".[1].memdev")
- memdevs="$mem0 $mem1 $mem2 $mem3"
-}
-
-setup_x3()
-{
- # find an x3 decoder
- decoder=$($CXL list -b cxl_test -D -d root | jq -r ".[] |
- select(.pmem_capable == true) |
- select(.nr_targets == 3) |
- .decoder")
-
- if [[ ! $decoder ]]; then
- echo "no x3 decoder found, skipping xor-x3 test"
- return
- fi
-
- # Find a memdev for each host-bridge interleave position
- port_dev0=$($CXL list -T -d "$decoder" | jq -r ".[] |
- .targets | .[] | select(.position == 0) | .target")
- port_dev1=$($CXL list -T -d "$decoder" | jq -r ".[] |
- .targets | .[] | select(.position == 1) | .target")
- port_dev2=$($CXL list -T -d "$decoder" | jq -r ".[] |
- .targets | .[] | select(.position == 2) | .target")
- mem0=$($CXL list -M -p "$port_dev0" | jq -r ".[0].memdev")
- mem1=$($CXL list -M -p "$port_dev1" | jq -r ".[0].memdev")
- mem2=$($CXL list -M -p "$port_dev2" | jq -r ".[0].memdev")
- memdevs="$mem0 $mem1 $mem2"
-}
-
-setup_x1
-create_and_destroy_region
-setup_x2
-create_and_destroy_region
-setup_x4
-create_and_destroy_region
-# x3 decoder may not be available in cxl/test topo yet
-setup_x3
-if [[ $decoder ]]; then
- create_and_destroy_region
-fi
-
-check_dmesg "$LINENO"
-
-modprobe -r cxl_test
diff --git a/test/meson.build b/test/meson.build
index 56aed9cc3c9d..5729d26d2a31 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -161,7 +161,6 @@ cxl_topo = find_program('cxl-topology.sh')
cxl_sysfs = find_program('cxl-region-sysfs.sh')
cxl_labels = find_program('cxl-labels.sh')
cxl_create_region = find_program('cxl-create-region.sh')
-cxl_xor_region = find_program('cxl-xor-region.sh')
cxl_update_firmware = find_program('cxl-update-firmware.sh')
cxl_events = find_program('cxl-events.sh')
cxl_sanitize = find_program('cxl-sanitize.sh')
@@ -198,7 +197,6 @@ tests = [
[ 'cxl-region-sysfs.sh', cxl_sysfs, 'cxl' ],
[ 'cxl-labels.sh', cxl_labels, 'cxl' ],
[ 'cxl-create-region.sh', cxl_create_region, 'cxl' ],
- [ 'cxl-xor-region.sh', cxl_xor_region, 'cxl' ],
[ 'cxl-events.sh', cxl_events, 'cxl' ],
[ 'cxl-sanitize.sh', cxl_sanitize, 'cxl' ],
[ 'cxl-destroy-region.sh', cxl_destroy_region, 'cxl' ],
--
2.37.3
^ permalink raw reply related [flat|nested] 4+ messages in thread* [ndctl PATCH 2/3] test/cxl-create-region.sh: deduplicate decoder and memdev lookups
2026-06-11 0:19 [ndctl PATCH 0/3] Add CXL region passthrough >16K gran test Alison Schofield
2026-06-11 0:19 ` [ndctl PATCH 1/3] test/cxl-create-region.sh: fold in XOR region coverage Alison Schofield
@ 2026-06-11 0:19 ` Alison Schofield
2026-06-11 0:19 ` [ndctl PATCH 3/3] test/cxl-create-region.sh: add passthrough >16K granularity test case Alison Schofield
2 siblings, 0 replies; 4+ messages in thread
From: Alison Schofield @ 2026-06-11 0:19 UTC (permalink / raw)
To: nvdimm, linux-cxl; +Cc: Alison Schofield
Several region setup helpers open-code the same decoder and memdev
lookups.
Factor the common queries into shared helpers. This reduces duplicate
logic and simplifies adding new region configuration tests.
No functional change.
Assisted-by: Claude:Opus-4-8
Signed-off-by: Alison Schofield <alison.schofield@intel.com>
---
test/cxl-create-region.sh | 73 ++++++++++++++++++---------------------
1 file changed, 33 insertions(+), 40 deletions(-)
diff --git a/test/cxl-create-region.sh b/test/cxl-create-region.sh
index d7a6840fed1a..5941e18f338d 100644
--- a/test/cxl-create-region.sh
+++ b/test/cxl-create-region.sh
@@ -25,17 +25,21 @@ destroy_regions()
fi
}
+# Find the pmem capable single-target root decoder for a memdev
+find_x1_decoder()
+{
+ $CXL list -b cxl_test -D -d root -m "$1" |
+ jq -r ".[] |
+ select(.pmem_capable == true) |
+ select(.nr_targets == 1) |
+ .decoder"
+}
+
create_x1_region()
{
mem="$1"
- # find a pmem capable root decoder for this mem
- decoder=$($CXL list -b cxl_test -D -d root -m "$mem" |
- jq -r ".[] |
- select(.pmem_capable == true) |
- select(.nr_targets == 1) |
- .decoder")
-
+ decoder=$(find_x1_decoder "$mem")
if [[ ! $decoder ]]; then
echo "no suitable decoder found for $mem, skipping"
return
@@ -69,13 +73,7 @@ create_subregions()
slice=$((256 << 20))
mem="$1"
- # find a pmem capable root decoder for this mem
- decoder=$($CXL list -b cxl_test -D -d root -m "$mem" |
- jq -r ".[] |
- select(.pmem_capable == true) |
- select(.nr_targets == 1) |
- .decoder")
-
+ decoder=$(find_x1_decoder "$mem")
if [[ ! $decoder ]]; then
echo "no suitable decoder found for $mem, skipping"
return
@@ -133,6 +131,17 @@ create_single()
destroy_regions "$region"
}
+# Find the index'th memdev behind the decoder's target at position
+find_memdev()
+{
+ local decoder="$1" position="$2" index="$3"
+ local port_dev
+
+ port_dev=$($CXL list -T -d "$decoder" | jq -r ".[] |
+ .targets | .[] | select(.position == $position) | .target")
+ $CXL list -M -p "$port_dev" | jq -r ".[$index].memdev"
+}
+
create_and_destroy_region()
{
region=$($CXL create-region -d "$decoder" -m "$memdevs" |
@@ -155,9 +164,7 @@ setup_x1()
.decoder")
# Find a memdev for this host-bridge
- port_dev0=$($CXL list -T -d "$decoder" | jq -r ".[] |
- .targets | .[] | select(.position == 0) | .target")
- mem0=$($CXL list -M -p "$port_dev0" | jq -r ".[0].memdev")
+ mem0=$(find_memdev "$decoder" 0 0)
memdevs="$mem0"
}
@@ -170,12 +177,8 @@ setup_x2()
.decoder")
# Find a memdev for each host-bridge interleave position
- port_dev0=$($CXL list -T -d "$decoder" | jq -r ".[] |
- .targets | .[] | select(.position == 0) | .target")
- port_dev1=$($CXL list -T -d "$decoder" | jq -r ".[] |
- .targets | .[] | select(.position == 1) | .target")
- mem0=$($CXL list -M -p "$port_dev0" | jq -r ".[0].memdev")
- mem1=$($CXL list -M -p "$port_dev1" | jq -r ".[0].memdev")
+ mem0=$(find_memdev "$decoder" 0 0)
+ mem1=$(find_memdev "$decoder" 1 0)
memdevs="$mem0 $mem1"
}
@@ -188,14 +191,10 @@ setup_x4()
.decoder")
# Find a memdev for each host-bridge interleave position
- port_dev0=$($CXL list -T -d "$decoder" | jq -r ".[] |
- .targets | .[] | select(.position == 0) | .target")
- port_dev1=$($CXL list -T -d "$decoder" | jq -r ".[] |
- .targets | .[] | select(.position == 1) | .target")
- mem0=$($CXL list -M -p "$port_dev0" | jq -r ".[0].memdev")
- mem1=$($CXL list -M -p "$port_dev1" | jq -r ".[0].memdev")
- mem2=$($CXL list -M -p "$port_dev0" | jq -r ".[1].memdev")
- mem3=$($CXL list -M -p "$port_dev1" | jq -r ".[1].memdev")
+ mem0=$(find_memdev "$decoder" 0 0)
+ mem1=$(find_memdev "$decoder" 1 0)
+ mem2=$(find_memdev "$decoder" 0 1)
+ mem3=$(find_memdev "$decoder" 1 1)
memdevs="$mem0 $mem1 $mem2 $mem3"
}
@@ -213,15 +212,9 @@ setup_x3()
fi
# Find a memdev for each host-bridge interleave position
- port_dev0=$($CXL list -T -d "$decoder" | jq -r ".[] |
- .targets | .[] | select(.position == 0) | .target")
- port_dev1=$($CXL list -T -d "$decoder" | jq -r ".[] |
- .targets | .[] | select(.position == 1) | .target")
- port_dev2=$($CXL list -T -d "$decoder" | jq -r ".[] |
- .targets | .[] | select(.position == 2) | .target")
- mem0=$($CXL list -M -p "$port_dev0" | jq -r ".[0].memdev")
- mem1=$($CXL list -M -p "$port_dev1" | jq -r ".[0].memdev")
- mem2=$($CXL list -M -p "$port_dev2" | jq -r ".[0].memdev")
+ mem0=$(find_memdev "$decoder" 0 0)
+ mem1=$(find_memdev "$decoder" 1 0)
+ mem2=$(find_memdev "$decoder" 2 0)
memdevs="$mem0 $mem1 $mem2"
}
--
2.37.3
^ permalink raw reply related [flat|nested] 4+ messages in thread* [ndctl PATCH 3/3] test/cxl-create-region.sh: add passthrough >16K granularity test case
2026-06-11 0:19 [ndctl PATCH 0/3] Add CXL region passthrough >16K gran test Alison Schofield
2026-06-11 0:19 ` [ndctl PATCH 1/3] test/cxl-create-region.sh: fold in XOR region coverage Alison Schofield
2026-06-11 0:19 ` [ndctl PATCH 2/3] test/cxl-create-region.sh: deduplicate decoder and memdev lookups Alison Schofield
@ 2026-06-11 0:19 ` Alison Schofield
2 siblings, 0 replies; 4+ messages in thread
From: Alison Schofield @ 2026-06-11 0:19 UTC (permalink / raw)
To: nvdimm, linux-cxl; +Cc: Alison Schofield
The CXL driver region configuration use to reject valid topologies
containing passthrough decoders beneath a wide parent interleave.
A recent kernel patch fixed that issue and extended cxl-test with
a topology that exercises it.
Add a create-and-destroy region case spanning the two host bridges
beneath the new 2-way 16K root decoder to verify that such
configurations are accepted.
The test case is quietly skipped if the new cxl/test topology is
not found, which also means the kernel fix is not yet present.
Assisted-by: Claude:Opus-4-8
Signed-off-by: Alison Schofield <alison.schofield@intel.com>
---
test/cxl-create-region.sh | 30 ++++++++++++++++++++++++++++--
1 file changed, 28 insertions(+), 2 deletions(-)
diff --git a/test/cxl-create-region.sh b/test/cxl-create-region.sh
index 5941e18f338d..c24e477c4f5c 100644
--- a/test/cxl-create-region.sh
+++ b/test/cxl-create-region.sh
@@ -170,10 +170,12 @@ setup_x1()
setup_x2()
{
- # Find an x2 decoder
+ # Find an x2 decoder. Pin to the 256 granularity root to avoid
+ # the 16K root used by the passthrough granularity test.
decoder=$($CXL list -b cxl_test -D -d root | jq -r ".[] |
select(.pmem_capable == true) |
select(.nr_targets == 2) |
+ select(.interleave_granularity == 256) |
.decoder")
# Find a memdev for each host-bridge interleave position
@@ -184,10 +186,12 @@ setup_x2()
setup_x4()
{
- # find an x2 decoder
+ # find an x2 decoder. Pin to the 256 granularity root to avoid
+ # the 16K root used by the passthrough granularity test.
decoder=$($CXL list -b cxl_test -D -d root | jq -r ".[] |
select(.pmem_capable == true) |
select(.nr_targets == 2) |
+ select(.interleave_granularity == 256) |
.decoder")
# Find a memdev for each host-bridge interleave position
@@ -198,6 +202,23 @@ setup_x4()
memdevs="$mem0 $mem1 $mem2 $mem3"
}
+setup_passthru_gran()
+{
+ # Find the 2-way 16K root. A region spanning both host bridges
+ # places one endpoint under each. The intermediate switch decoders
+ # are passthrough decoders with 32K granularity.
+ decoder=$($CXL list -b cxl_test -D -d root | jq -r ".[] |
+ select(.pmem_capable == true) |
+ select(.nr_targets == 2) |
+ select(.interleave_granularity == 16384) |
+ .decoder")
+
+ # Find a memdev for each host-bridge interleave position
+ mem0=$(find_memdev "$decoder" 0 0)
+ mem1=$(find_memdev "$decoder" 1 0)
+ memdevs="$mem0 $mem1"
+}
+
setup_x3()
{
# find an x3 decoder
@@ -252,6 +273,11 @@ setup_x3
if [[ $decoder ]]; then
create_and_destroy_region
fi
+# 16K root may not be available in cxl/test topo yet
+setup_passthru_gran
+if [[ $decoder ]]; then
+ create_and_destroy_region
+fi
check_dmesg "$LINENO"
--
2.37.3
^ permalink raw reply related [flat|nested] 4+ messages in thread