The throtl test group uses null_blk devices as test target in its test cases. To prepare for supporting scsi_debug device as the additional test target, introduce three helper functions below to abstract null_blk specific operations: _configure_throtl_blkdev() : Sets up the null_blk device _delete_throtl_blkdev() : Removes the null_blk device for testing _exit_throtl_blkdev() : Cleans up the null_blk device Support two options of _configure_throtl_blkdev(), --sector_size and --memory_backed so that each test case can tailor the setup according to specific requirements. Signed-off-by: Shin'ichiro Kawasaki --- tests/throtl/002 | 5 ++--- tests/throtl/003 | 5 ++--- tests/throtl/004 | 2 +- tests/throtl/006 | 2 +- tests/throtl/007 | 5 ++--- tests/throtl/rc | 45 ++++++++++++++++++++++++++++++++++++++++++--- 6 files changed, 50 insertions(+), 14 deletions(-) diff --git a/tests/throtl/002 b/tests/throtl/002 index 02b0969..bed876d 100755 --- a/tests/throtl/002 +++ b/tests/throtl/002 @@ -13,14 +13,13 @@ QUICK=1 test() { echo "Running ${TEST_NAME}" - local page_size max_secs + local page_size local io_size_kb block_size local iops=256 page_size=$(getconf PAGE_SIZE) - max_secs=$((page_size / 512)) - if ! _set_up_throtl max_sectors="${max_secs}"; then + if ! _set_up_throtl --sector_size "${page_size}"; then return 1; fi diff --git a/tests/throtl/003 b/tests/throtl/003 index 8276d87..d76a0d5 100755 --- a/tests/throtl/003 +++ b/tests/throtl/003 @@ -13,11 +13,10 @@ QUICK=1 test() { echo "Running ${TEST_NAME}" - local page_size max_secs + local page_size page_size=$(getconf PAGE_SIZE) - max_secs=$((page_size / 512)) - if ! _set_up_throtl max_sectors="${max_secs}"; then + if ! _set_up_throtl --sector_size "${page_size}"; then return 1; fi diff --git a/tests/throtl/004 b/tests/throtl/004 index d1461b9..d623097 100755 --- a/tests/throtl/004 +++ b/tests/throtl/004 @@ -26,7 +26,7 @@ test() { } & sleep 0.6 - echo 0 > "/sys/kernel/config/nullb/$THROTL_DEV/power" + _delete_throtl_blkdev wait $! _clean_up_throtl diff --git a/tests/throtl/006 b/tests/throtl/006 index b6f47d1..263415f 100755 --- a/tests/throtl/006 +++ b/tests/throtl/006 @@ -34,7 +34,7 @@ test_meta_io() { test() { echo "Running ${TEST_NAME}" - if ! _set_up_throtl memory_backed=1; then + if ! _set_up_throtl --memory_backed; then return 1; fi diff --git a/tests/throtl/007 b/tests/throtl/007 index ae59c6f..83d8dc7 100755 --- a/tests/throtl/007 +++ b/tests/throtl/007 @@ -14,11 +14,10 @@ QUICK=1 test() { echo "Running ${TEST_NAME}" - local page_size max_secs + local page_size page_size=$(getconf PAGE_SIZE) - max_secs=$((page_size / 512)) - if ! _set_up_throtl max_sectors="${max_secs}"; then + if ! _set_up_throtl --sector_size "${page_size}"; then return 1; fi diff --git a/tests/throtl/rc b/tests/throtl/rc index 327084b..d20dc94 100644 --- a/tests/throtl/rc +++ b/tests/throtl/rc @@ -21,15 +21,54 @@ group_requires() { _have_program bc } +_configure_throtl_blkdev() { + local sector_size=0 memory_backed=0 + local -a args + + while [[ $# -gt 0 ]]; do + case $1 in + --sector_size) + sector_size="$2" + shift 2 + ;; + --memory_backed) + memory_backed=1 + shift + ;; + *) + echo "WARNING: unknown argument: $1" + shift + ;; + esac + done + + args=("$THROTL_DEV") + ((sector_size)) && args+=(max_sectors="$((sector_size / 512))") + ((memory_backed)) && args+=(memory_backed=1) + if _configure_null_blk "${args[@]}" power=1; then + return + fi + return 1 +} + +_delete_throtl_blkdev() { + echo 0 > "/sys/kernel/config/nullb/$THROTL_DEV/power" +} + +_exit_throtl_blkdev() { + _exit_null_blk + unset THROTL_DEV +} + # Create a new null_blk device, and create a new blk-cgroup for test. _set_up_throtl() { - if ! _configure_null_blk $THROTL_DEV "$@" power=1; then + if ! _configure_throtl_blkdev "$@"; then return 1 fi if ! _init_cgroup2; then - _exit_null_blk + _exit_throtl_blkdev return 1 fi @@ -58,7 +97,7 @@ _clean_up_throtl() { fi _exit_cgroup2 - _exit_null_blk + _exit_throtl_blkdev } _throtl_set_limits() { -- 2.51.0 Currently, the test case throtl/002 assumes that the test target device is null_blk. For null_blk, it is possible to specify the page size as the maximum I/O size during set up. However, in the case of scsi_debug, the maximum I/O size is not configurable, causing the test case to fail when the test case is extended to support scsi_debug. To prevent the failure, set the maximum I/O size after the test device is initialized, regardless of the device type. To achieve this, add a new helper function _throtl_set_max_io_size() which modifies the sysfs attribute max_sectors_kb to adjust the maximum I/O size for the device. Suggested-by: Yu Kuai Signed-off-by: Shin'ichiro Kawasaki --- tests/throtl/002 | 5 ++++- tests/throtl/rc | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/throtl/002 b/tests/throtl/002 index bed876d..87b9f91 100755 --- a/tests/throtl/002 +++ b/tests/throtl/002 @@ -24,7 +24,10 @@ test() { fi io_size_kb=$(($(_throtl_get_max_io_size) * 1024)) - block_size=$((iops * io_size_kb)) + if [ "${io_size_kb}" -gt "${page_size}" ]; then + _throtl_set_max_io_size $((page_size / 1024)) + fi + block_size=$((iops * page_size)) _throtl_set_limits wiops="${iops}" _throtl_test_io write "${block_size}" 1 diff --git a/tests/throtl/rc b/tests/throtl/rc index d20dc94..8c25b1a 100644 --- a/tests/throtl/rc +++ b/tests/throtl/rc @@ -114,6 +114,10 @@ _throtl_get_max_io_size() { cat "/sys/block/$THROTL_DEV/queue/max_sectors_kb" } +_throtl_set_max_io_size() { + echo "$1" > "/sys/block/$THROTL_DEV/queue/max_sectors_kb" +} + _throtl_issue_fs_io() { local path=$1 local start_time -- 2.51.0 Currently, the test case throtl/004 assumes that the test target device is null_blk. When it verifies the dd command error message, it checks the string "/dev/dev_nullb" also. However, this test will fail when the test case is extended to support scsi_debug. To avoid the failure, remove dependency on the specific device name. Save the dd command error output to the FULL file, and check only the error message part in the FULL file. Signed-off-by: Shin'ichiro Kawasaki --- tests/throtl/004 | 4 +++- tests/throtl/004.out | 3 +-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/throtl/004 b/tests/throtl/004 index d623097..777afcf 100755 --- a/tests/throtl/004 +++ b/tests/throtl/004 @@ -22,7 +22,7 @@ test() { { echo "$BASHPID" > "$CGROUP2_DIR/$THROTL_DIR/cgroup.procs" - _throtl_issue_io write 10M 1 + _throtl_issue_io write 10M 1 &>> "$FULL" } & sleep 0.6 @@ -30,5 +30,7 @@ test() { wait $! _clean_up_throtl + + grep --only-matching "Input/output error" "$FULL" echo "Test complete" } diff --git a/tests/throtl/004.out b/tests/throtl/004.out index e76ec3a..3997531 100644 --- a/tests/throtl/004.out +++ b/tests/throtl/004.out @@ -1,4 +1,3 @@ Running throtl/004 -dd: error writing '/dev/dev_nullb': Input/output error -1 +Input/output error Test complete -- 2.51.0 Currently, the throtl test cases set up null_blk devices as test targets. It is desired to run the tests with scsi_debug devices also to expand test coverage and identify failures that do not surface with null_blk as shown in the Link. Introduce the global variable throtl_blkdev_type to choose the test target block device type. When 'nullb' is set to it, run the tests with null_blk. When 'sdebug' is set, run with scsi_debug. The command line below runs the throtl group with scsi_debug. $ sudo bash -c "throtl_blkdev_type=sdebug ./check throtl" Modify the helper functions _configure_throtl_blkdev(), _delete_throtl_blkdev() and _exit_throtl_blkdev() to support both null_blk and scsi_debug. After this change, the global variable THROTL_DEV is no longer constant then shellcheck warns about its references. Add double quotations to suppress the shellcheck warnings. Link: https://lore.kernel.org/linux-block/20250918085341.3686939-1-yukuai1@huaweicloud.com/ Signed-off-by: Shin'ichiro Kawasaki --- tests/throtl/rc | 63 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 50 insertions(+), 13 deletions(-) diff --git a/tests/throtl/rc b/tests/throtl/rc index 8c25b1a..f5eb84e 100644 --- a/tests/throtl/rc +++ b/tests/throtl/rc @@ -6,21 +6,26 @@ . common/rc . common/null_blk +. common/scsi_debug . common/cgroup THROTL_DIR=$(echo "$TEST_NAME" | tr '/' '_') -THROTL_DEV=dev_nullb +throtl_blkdev_type=${throtl_blkdev_type:-"nullb"} +THROTL_NULL_DEV=dev_nullb +declare THROTL_DEV declare THROTL_CLEAR_BASE_SUBTREE_CONTROL_IO declare THROTL_CLEAR_CGROUP2_DIR_CONTROL_IO group_requires() { _have_root _have_null_blk + _have_scsi_debug _have_kernel_option BLK_DEV_THROTTLING _have_cgroup2_controller io _have_program bc } +# Prepare null_blk or scsi_debug device to test, based on throtl_blkdev_type. _configure_throtl_blkdev() { local sector_size=0 memory_backed=0 local -a args @@ -42,21 +47,53 @@ _configure_throtl_blkdev() { esac done - args=("$THROTL_DEV") - ((sector_size)) && args+=(max_sectors="$((sector_size / 512))") - ((memory_backed)) && args+=(memory_backed=1) - if _configure_null_blk "${args[@]}" power=1; then - return - fi + THROTL_DEV= + case "$throtl_blkdev_type" in + nullb) + args=("$THROTL_NULL_DEV") + ((sector_size)) && args+=(max_sectors="$((sector_size / 512))") + ((memory_backed)) && args+=(memory_backed=1) + if _configure_null_blk "${args[@]}" power=1; then + THROTL_DEV=$THROTL_NULL_DEV + return + fi + ;; + sdebug) + args=(dev_size_mb=1024) + ((sector_size)) && args+=(sector_size="${sector_size}") + if _configure_scsi_debug "${args[@]}"; then + THROTL_DEV=${SCSI_DEBUG_DEVICES[0]} + return + fi + ;; + *) + echo "Invalid block device type: ${throtl_blkdev_type}" ;; + esac return 1 } _delete_throtl_blkdev() { - echo 0 > "/sys/kernel/config/nullb/$THROTL_DEV/power" + case "$throtl_blkdev_type" in + nullb) + echo 0 > "/sys/kernel/config/nullb/$THROTL_DEV/power" + ;; + sdebug) + echo 1 > "/sys/block/$THROTL_DEV/device/delete" + ;; + *) + echo "Invalid block device type: ${throtl_blkdev_type}" ;; + esac } _exit_throtl_blkdev() { - _exit_null_blk + case "$throtl_blkdev_type" in + nullb) + _exit_null_blk ;; + sdebug) + _exit_scsi_debug ;; + *) + echo "Invalid block device type: ${throtl_blkdev_type}" ;; + esac unset THROTL_DEV } @@ -101,12 +138,12 @@ _clean_up_throtl() { } _throtl_set_limits() { - echo "$(cat /sys/block/$THROTL_DEV/dev) $*" > \ + echo "$(cat /sys/block/"$THROTL_DEV"/dev) $*" > \ "$CGROUP2_DIR/$THROTL_DIR/io.max" } _throtl_remove_limits() { - echo "$(cat /sys/block/$THROTL_DEV/dev) rbps=max wbps=max riops=max wiops=max" > \ + echo "$(cat /sys/block/"$THROTL_DEV"/dev) rbps=max wbps=max riops=max wiops=max" > \ "$CGROUP2_DIR/$THROTL_DIR/io.max" } @@ -145,9 +182,9 @@ _throtl_issue_io() { start_time=$(date +%s.%N) if [ "$1" == "read" ]; then - dd if=/dev/$THROTL_DEV of=/dev/null bs="$2" count="$3" iflag=direct status=none + dd if=/dev/"$THROTL_DEV" of=/dev/null bs="$2" count="$3" iflag=direct status=none elif [ "$1" == "write" ]; then - dd of=/dev/$THROTL_DEV if=/dev/zero bs="$2" count="$3" oflag=direct status=none + dd of=/dev/"$THROTL_DEV" if=/dev/zero bs="$2" count="$3" oflag=direct status=none fi end_time=$(date +%s.%N) -- 2.51.0 The previous commit introduced the global variable throtl_blkdev_type to specify the type of block device for the throtl group. However, users need to run tests twice modifying the variable's value each time to test against both device types null_blk and scsi_debug. This workflow is cumbersome. To run the throtl group for both null_blk and scsi_debug in a single run, introduce the global variable THROTL_BLKDEV_TYPES instead of throtl_blkdev_type. When THROTL_BLKDEV_TYPES is set to 'nullb sdebug', the blktests framework executes each test case in the throtl group for both null_blk and scsi_debug sequentially. For this purpose, introduce the helper function _set_throtl_blkdev_type() and call it in set_conditions() hooks of the test cases. Each of the two command lines below runs the throtl group with both null_blk and scsi_debug. Please note that the default value of THROTL_BLKDEV_TYPES is 'nullb sdebug'. $ sudo bash -c "./check throtl/" $ sudo bash -c "THROTL_BLKDEV_TYPES='nullb sdebug' ./check throtl/" Each of the command lines below runs the throtl group only for null_blk or scsi_debug, respectively. $ sudo bash -c "THROTL_BLKDEV_TYPES='nullb' ./check throtl/" $ sudo bash -c "THROTL_BLKDEV_TYPES='sdebug' ./check throtl/" Signed-off-by: Shin'ichiro Kawasaki --- Documentation/running-tests.md | 17 +++++++++++++++++ tests/throtl/001 | 4 ++++ tests/throtl/002 | 4 ++++ tests/throtl/003 | 4 ++++ tests/throtl/004 | 4 ++++ tests/throtl/005 | 4 ++++ tests/throtl/006 | 4 ++++ tests/throtl/007 | 4 ++++ tests/throtl/rc | 16 ++++++++++++++++ 9 files changed, 61 insertions(+) diff --git a/Documentation/running-tests.md b/Documentation/running-tests.md index 8ccd739..4cf1a3a 100644 --- a/Documentation/running-tests.md +++ b/Documentation/running-tests.md @@ -167,6 +167,23 @@ USE_RXE=1 ./check srp/ 'USE_RXE' had the old name 'use_rxe'. The old name is still usable but not recommended. +### Blk-throttle tests + +The blk-throttle tests has one environment variable below: + +- THROTL_BLKDEV_TYPES: 'nullb' 'sdebug' + Set up test target block device based on this environment variable value. To + test with null_blk, set 'nullb'. To test with scsi_debug, set 'sdebug'. To + test with both, set 'nullb sdebug'. Default value is 'nullb sdebug'. + +```sh +To run with scsi_debug: +THROTL_BLKDEV_TYPES="sdebug" ./check throtl/ + +To run with both null_blk and scsi_debug: +THROTL_BLKDEV_TYPES="nullb sdebug" ./check throtl/ +``` + ### Normal user To run test cases which require normal user privilege, prepare a user and diff --git a/tests/throtl/001 b/tests/throtl/001 index 835cac2..89a5892 100755 --- a/tests/throtl/001 +++ b/tests/throtl/001 @@ -9,6 +9,10 @@ DESCRIPTION="basic functionality" QUICK=1 +set_conditions() { + _set_throtl_blkdev_type "$@" +} + test() { echo "Running ${TEST_NAME}" diff --git a/tests/throtl/002 b/tests/throtl/002 index 87b9f91..08e685f 100755 --- a/tests/throtl/002 +++ b/tests/throtl/002 @@ -10,6 +10,10 @@ DESCRIPTION="iops limit over IO split" QUICK=1 +set_conditions() { + _set_throtl_blkdev_type "$@" +} + test() { echo "Running ${TEST_NAME}" diff --git a/tests/throtl/003 b/tests/throtl/003 index d76a0d5..700e9e6 100755 --- a/tests/throtl/003 +++ b/tests/throtl/003 @@ -10,6 +10,10 @@ DESCRIPTION="bps limit over IO split" QUICK=1 +set_conditions() { + _set_throtl_blkdev_type "$@" +} + test() { echo "Running ${TEST_NAME}" diff --git a/tests/throtl/004 b/tests/throtl/004 index 777afcf..b1f6110 100755 --- a/tests/throtl/004 +++ b/tests/throtl/004 @@ -11,6 +11,10 @@ DESCRIPTION="delete disk while IO is throttled" QUICK=1 +set_conditions() { + _set_throtl_blkdev_type "$@" +} + test() { echo "Running ${TEST_NAME}" diff --git a/tests/throtl/005 b/tests/throtl/005 index 86e52b3..7691ad1 100755 --- a/tests/throtl/005 +++ b/tests/throtl/005 @@ -10,6 +10,10 @@ DESCRIPTION="change config with throttled IO" QUICK=1 +set_conditions() { + _set_throtl_blkdev_type "$@" +} + test() { echo "Running ${TEST_NAME}" diff --git a/tests/throtl/006 b/tests/throtl/006 index 263415f..2dcf3a3 100755 --- a/tests/throtl/006 +++ b/tests/throtl/006 @@ -15,6 +15,10 @@ requires() { _have_driver ext4 } +set_conditions() { + _set_throtl_blkdev_type "$@" +} + test_meta_io() { local path="$1" local start_time diff --git a/tests/throtl/007 b/tests/throtl/007 index 83d8dc7..97dece6 100755 --- a/tests/throtl/007 +++ b/tests/throtl/007 @@ -11,6 +11,10 @@ DESCRIPTION="bps limit with iops limit over io split" QUICK=1 +set_conditions() { + _set_throtl_blkdev_type "$@" +} + test() { echo "Running ${TEST_NAME}" diff --git a/tests/throtl/rc b/tests/throtl/rc index f5eb84e..d1afefd 100644 --- a/tests/throtl/rc +++ b/tests/throtl/rc @@ -10,6 +10,7 @@ . common/cgroup THROTL_DIR=$(echo "$TEST_NAME" | tr '/' '_') +THROTL_BLKDEV_TYPES=${THROTL_BLKDEV_TYPES:-"nullb sdebug"} throtl_blkdev_type=${throtl_blkdev_type:-"nullb"} THROTL_NULL_DEV=dev_nullb declare THROTL_DEV @@ -25,6 +26,21 @@ group_requires() { _have_program bc } +_set_throtl_blkdev_type() { + local index=$1 + local -a types + + read -r -a types <<< "${THROTL_BLKDEV_TYPES[@]}" + + if [[ -z $index ]]; then + echo ${#types[@]} + return + fi + + throtl_blkdev_type=${types[index]} + COND_DESC="${throtl_blkdev_type}" +} + # Prepare null_blk or scsi_debug device to test, based on throtl_blkdev_type. _configure_throtl_blkdev() { local sector_size=0 memory_backed=0 -- 2.51.0