Existing tests use single-range devices and cannot detect incorrect memory block accounting across discontiguous mappings. A two-range device exposed this bug by reporting only one of its two blocks.
Create a device with two separated mappings and verify its memory block count against the expected count from both mappings. Signed-off-by: Alison Schofield <[email protected]> --- test/daxctl-create.sh | 58 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/test/daxctl-create.sh b/test/daxctl-create.sh index 954a112d0f18..c4fe369eac3a 100755 --- a/test/daxctl-create.sh +++ b/test/daxctl-create.sh @@ -7,6 +7,9 @@ rc=77 trap 'cleanup $LINENO' ERR +policy=/sys/devices/system/memory/auto_online_blocks +saved_policy= + modprobe -r cxl_test modprobe cxl_test $CXL list @@ -14,6 +17,7 @@ $CXL list cleanup() { printf "Error at line %d\n" "$1" + [[ $saved_policy ]] && echo "$saved_policy" > "$policy" [[ $testdev ]] && reset_dax exit $rc } @@ -396,6 +400,59 @@ daxctl_test7() test_pass } +# Test 8: multi-range system-ram +# Successfully counts every memory block of a device whose two ranges +# have a gap between them. The memory is never onlined: cxl_test memory +# is not backed by RAM. +daxctl_test8() +{ + local daxdev_1 daxdev_2 daxdev path m start end n nmaps=0 total=0 + local bs size + + bs=$((0x$(cat /sys/devices/system/memory/block_size_bytes))) + size=$((available / 4)) + if (( size < bs || size % bs )); then + echo "test8: skipped, region too small for $bs byte memory blocks" + return 0 + fi + + # a devdax device in the gap between the two ranges, it has no + # memory blocks to be miscounted + daxdev_1=$("$DAXCTL" create-device -r "$region_id" -s $size | jq -er '.[].chardev') + daxdev_2=$("$DAXCTL" create-device -r "$region_id" -s $size | jq -er '.[].chardev') + test -n "$daxdev_2" + "$DAXCTL" disable-device "$daxdev_1" && "$DAXCTL" destroy-device "$daxdev_1" + + daxdev=$("$DAXCTL" create-device -r "$region_id" -s $((size * 2)) | jq -er '.[].chardev') + test "$(daxctl_get_nr_mappings "$daxdev")" -eq 2 + + # memory blocks wholly inside each mapping + path=$(readlink -f /sys/bus/dax/devices/"$daxdev") + for m in "$path"/mapping[0-9]*; do + start=$(cat "$m"/start) + end=$(cat "$m"/end) + n=$(((end + 1) / bs - (start + bs - 1) / bs)) + (( n > 0 )) + total=$((total + n)) + nmaps=$((nmaps + 1)) + done + test "$nmaps" -eq 2 + + saved_policy=$(cat "$policy") + echo offline > "$policy" + "$DAXCTL" reconfigure-device -N -m system-ram "$daxdev" + test "$("$DAXCTL" list -d "$daxdev" | jq -er '.[].total_memblocks')" -eq "$total" + "$DAXCTL" reconfigure-device -m devdax "$daxdev" + echo "$saved_policy" > "$policy" + saved_policy= + + "$DAXCTL" disable-device -r "$region_id" all + "$DAXCTL" destroy-device -r "$region_id" all + + clear_dev + test_pass +} + find_testdev rc=1 setup_dev @@ -407,6 +464,7 @@ daxctl_test4 daxctl_test5 daxctl_test6 daxctl_test7 +daxctl_test8 reset_dev modprobe -r cxl_test exit 0 -- 2.37.3
