Add a test case to validate that all switch port decoders sharing downstream ports, dports, have target lists properly enumerated.
This test catches the regression fixed by a recent kernel patch[1] where only one decoder per switch port has targets populated while others have nr_targets=0, even when dports are available. This test is based on the current cxl_test topology which provides multiple switch ports with 8 decoders each. Like other testcases in cxl-topology.sh, if the cxl_test topology changes (number of switches, decoders per port, or hierarchy), this test will need corresponding updates. This new case is quietly skipped with kernel version 6.18 where it is known broken. [1] https://lore.kernel.org/linux-cxl/[email protected]/ Signed-off-by: Alison Schofield <[email protected]> --- test/common | 12 +++++++++++ test/cxl-topology.sh | 51 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/test/common b/test/common index 2d076402ef7c..2eb11b7396d0 100644 --- a/test/common +++ b/test/common @@ -101,6 +101,18 @@ check_min_kver() [[ "$ver" == "$(echo -e "$ver\n$KVER" | sort -V | head -1)" ]] } +# check_eq_kver +# $1: Kernel version to match. format: X.Y +# +check_eq_kver() +{ + local ver="$1" + : "${KVER:=$(uname -r)}" + + [ -n "$ver" ] || return 1 + [[ "$KVER" == "$ver"* ]] +} + # do_skip # $1: Skip message # diff --git a/test/cxl-topology.sh b/test/cxl-topology.sh index b68cb8b262b6..d9475b1bae9c 100644 --- a/test/cxl-topology.sh +++ b/test/cxl-topology.sh @@ -151,6 +151,57 @@ count=$(jq "map(select(.pmem_size == $pmem_size)) | length" <<< $json) ((bridges == 2 && count == 8 || bridges == 3 && count == 10 || bridges == 4 && count == 11)) || err "$LINENO" +# Test that switch port decoders have complete target list enumeration +# Validates a fix for multiple decoders sharing the same dport. +# Based on the cxl_test topology expectation of switch ports at depth 2 +# with 8 decoders each. Adjust if that expectation changes. +test_switch_decoder_target_enumeration() { + + # Get verbose output to see targets arrays + json=$($CXL list -b cxl_test -vvv) + + switch_port_issues=$(jq ' + # Find all switch ports (depth 2) + [.. | objects | select(.depth == 2 and has("decoders:" + .port))] | + + # For each switch port, analyze its decoder target pattern + map({ + port: .port, + nr_dports: .nr_dports, + + # Count non-endpoint decoders (no "mode" field) + total: ([to_entries[] | select(.key | startswith("decoders:")) + | .value[] | select(has("mode") == false)] | + length), + + # Count how many have targets + with_targets: ([to_entries[] | select(.key | + startswith("decoders:")) | .value[] | + select(has("mode") == false and .nr_targets > 0)] | + length), + + # Count how many explicitly have no targets + without_targets: ([to_entries[] | select(.key | + startswith("decoders:")) | .value[] | + select(has("mode") == false and .nr_targets == 0)] | + length) + }) | + + # Filter for the expected pattern and count them + map(select(.nr_dports > 0 and + .with_targets == 1 and + .without_targets >= 7)) | + length + ' <<<"$json") + + ((switch_port_issues == 0)) || { + echo "Found $switch_port_issues switch ports with incomplete target enumeration" + echo "Only 1 decoder has targets while 7+ have nr_targets=0" + err "$LINENO" + } +} +# Skip the target enumeration test where known broken +check_eq_kver 6.18 || test_switch_decoder_target_enumeration # check that switch ports disappear after all of their memdevs have been # disabled, and return when the memdevs are enabled. -- 2.37.3
