On Sep 18, 2025 / 16:53, Yu Kuai wrote: > From: Yu Kuai <yukuai3@xxxxxxxxxx> > > While I'm looking at another deadlock issue for blk-throtl, it's found > during test that lockdep is reporting another issue quite eazy, I'm > adding regerssion test for now, if anyone is interested. Otherwise, I'll > go back for this after I finish the problem at hand later. > > BTW, maybe we can support to test for scsi_debug instead of null_blk for > all the throtl tests. This is a good chance to use blktests' feature to repeat test cases by different conditions [1]. Test cases can implement set_conditions() hooks for that purpose. [1] https://github.com/linux-blktests/blktests/blob/a997ab0ca9b77ddf31b8c632bfe57f7bd75e305e/new#L183 Yu, FYI, I quickly implemented the set_conditions() hooks for the throtl group, and attach it as a patch. When you have time, please try it out. Each test case runs twice for null_blk and scsi_debug [2]. - With this patch, the lockdep splat is recreated at throtl/004. It is observed at throtl/001 also as show in [2]. - throtl/002 fails for scsi_debug. I guess performance difference between null_blk and scsi_debug is the cause, but not so sure. - Results are placed in results/nodev_nullb and results/nodev_sdebug. If you think this approach is good, I will prepare a formal patch series. [2] # ./check throtl throtl/001 (nullb) (basic functionality) [passed] runtime 4.546s ... 4.753s throtl/001 (sdebug) (basic functionality) [failed] runtime 5.386s ... 5.842s something found in dmesg: [ 79.444897] [ T1156] run blktests throtl/001 at 2025-09-23 17:05:22 [ 79.684859] [ T1260] sd 9:0:0:0: [sdd] Synchronizing SCSI cache [ 80.002576] [ T1262] scsi_debug:sdebug_driver_probe: scsi_debug: trim poll_queues to 0. poll_q/nr_hw = (0/1) [ 80.003950] [ T1262] scsi host9: scsi_debug: version 0191 [20210520] dev_size_mb=1024, opts=0x0, submit_queues=1, statistics=0 [ 80.009307] [ T1262] scsi 9:0:0:0: Direct-Access Linux scsi_debug 0191 PQ: 0 ANSI: 7 [ 80.011952] [ C2] scsi 9:0:0:0: Power-on or device reset occurred [ 80.018583] [ T1262] sd 9:0:0:0: Attached scsi generic sg3 type 0 [ 80.020594] [ T103] sd 9:0:0:0: [sdd] 2097152 512-byte logical blocks: (1.07 GB/1.00 GiB) [ 80.022826] [ T103] sd 9:0:0:0: [sdd] Write Protect is off ... (See '/home/shin/Blktests/blktests/results/nodev_sdebug/throtl/001.dmesg' for the entire message) throtl/002 (nullb) (iops limit over IO split) [passed] runtime 2.586s ... 2.486s throtl/002 (sdebug) (iops limit over IO split) [failed] runtime 6.137s ... 6.467s --- tests/throtl/002.out 2025-09-23 14:05:35.011885439 +0900 +++ /home/shin/Blktests/blktests/results/nodev_sdebug/throtl/002.out.bad 2025-09-23 17:05:37.209794003 +0900 @@ -1,4 +1,4 @@ Running throtl/002 -1 -1 +3 +3 Test complete throtl/003 (nullb) (bps limit over IO split) [passed] runtime 2.554s ... 2.424s throtl/003 (sdebug) (bps limit over IO split) [passed] runtime 3.075s ... 2.924s throtl/004 (nullb) (delete disk while IO is throttled) [passed] runtime 1.269s ... 1.071s throtl/004 (sdebug) (delete disk while IO is throttled) [passed] runtime 2.142s ... 1.471s throtl/005 (nullb) (change config with throttled IO) [passed] runtime 3.345s ... 3.420s throtl/005 (sdebug) (change config with throttled IO) [passed] runtime 3.905s ... 3.984s throtl/006 (nullb) (test if meta IO has higher priority than data IO) [passed] runtime 13.014s ... 13.086s throtl/006 (sdebug) (test if meta IO has higher priority than data IO) [passed] runtime 5.715s ... 5.631s throtl/007 (nullb) (bps limit with iops limit over io split) [passed] runtime 4.527s ... 4.476s throtl/007 (sdebug) (bps limit with iops limit over io split) [passed] runtime 5.065s ... 5.043s
From 240a54ea479c156a5fed0f831fa084b138159e7e Mon Sep 17 00:00:00 2001 From: Shin'ichiro Kawasaki <shinichiro.kawasaki@xxxxxxx> Date: Tue, 23 Sep 2025 15:58:44 +0900 Subject: [PATCH] throtl: introduce THROTL_BLKDEV_TYPES Currently, the test cases of throtl group run tests for null_blk. However, it was found that some bugs are not revealed with null_blk. It is required to run the test cases with scsi_debug to recreate such bugs. To run the existing test cases for both null_blk and scsi_debug, introduce the environmental variable THROTL_BLKDEV_TYPES. Its default value is "nullb sdebug", which indicates to run the test cases for both null_blk and scsi_debug. When the variable has only "nullb" or "sdebug", the test cases are run only for null_blk or scsi_debug respectively. Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@xxxxxxx> --- Documentation/running-tests.md | 17 ++++++ tests/throtl/001 | 4 ++ tests/throtl/002 | 9 ++- tests/throtl/003 | 9 ++- tests/throtl/004 | 10 +++- tests/throtl/004.out | 3 +- tests/throtl/005 | 4 ++ tests/throtl/006 | 6 +- tests/throtl/007 | 9 ++- tests/throtl/rc | 106 ++++++++++++++++++++++++++++++--- 10 files changed, 156 insertions(+), 21 deletions(-) diff --git a/Documentation/running-tests.md b/Documentation/running-tests.md index a42fc91..0dc9853 100644 --- a/Documentation/running-tests.md +++ b/Documentation/running-tests.md @@ -150,6 +150,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'. + Default value is 'nullb sdebug' which specifies both. + +```sh +To run with null_blk: +THROTL_BLKDEV_TYPES="nullb" ./check throtl/ + +To run with scsi_debug: +THROTL_BLKDEV_TYPES="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 02b0969..b082b99 100755 --- a/tests/throtl/002 +++ b/tests/throtl/002 @@ -10,17 +10,20 @@ DESCRIPTION="iops limit over IO split" QUICK=1 +set_conditions() { + _set_throtl_blkdev_type "$@" +} + 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..700e9e6 100755 --- a/tests/throtl/003 +++ b/tests/throtl/003 @@ -10,14 +10,17 @@ DESCRIPTION="bps limit over IO split" QUICK=1 +set_conditions() { + _set_throtl_blkdev_type "$@" +} + 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..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}" @@ -22,13 +26,15 @@ 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 - echo 0 > "/sys/kernel/config/nullb/$THROTL_DEV/power" + _delete_throtl_blkdev 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 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 b6f47d1..a13092e 100755 --- a/tests/throtl/006 +++ b/tests/throtl/006 @@ -10,6 +10,10 @@ DESCRIPTION="test if meta IO has higher priority than data IO" QUICK=1 +set_conditions() { + _set_throtl_blkdev_type "$@" +} + requires() { _have_program mkfs.ext4 _have_driver ext4 @@ -34,7 +38,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..97dece6 100755 --- a/tests/throtl/007 +++ b/tests/throtl/007 @@ -11,14 +11,17 @@ DESCRIPTION="bps limit with iops limit over io split" QUICK=1 +set_conditions() { + _set_throtl_blkdev_type "$@" +} + 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..1b6453c 100644 --- a/tests/throtl/rc +++ b/tests/throtl/rc @@ -6,25 +6,117 @@ . common/rc . common/null_blk +. common/scsi_debug . common/cgroup THROTL_DIR=$(echo "$TEST_NAME" | tr '/' '_') -THROTL_DEV=dev_nullb +THROTL_BLKDEV_TYPES=${THROTL_BLKDEV_TYPES:-"nullb sdebug"} +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 } +_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 + 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 + + 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() { + 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() { + 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 +} + # 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 @@ -58,16 +150,16 @@ _clean_up_throtl() { fi _exit_cgroup2 - _exit_null_blk + _exit_throtl_blkdev } _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" } @@ -102,9 +194,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