There's currently no tests to verify wbt is working properly, this patch
fixes that.  Simply run a varied workload and measure the read latencies
with wbt off, and then turn it on and verify that the read latencies go
down.

Signed-off-by: Josef Bacik <jo...@toxicpanda.com>
---
 common/fio          |  8 +++++
 common/rc           |  8 +++++
 tests/block/022     | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 tests/block/022.out |  2 ++
 tests/block/026     | 12 ++-----
 5 files changed, 114 insertions(+), 10 deletions(-)
 create mode 100755 tests/block/022
 create mode 100644 tests/block/022.out

diff --git a/common/fio b/common/fio
index e407088840b8..9e1a0557ac61 100644
--- a/common/fio
+++ b/common/fio
@@ -192,3 +192,11 @@ _fio_perf_report() {
                TEST_RUN["$FIO_PERF_PREFIX$name"]="$value"
        done
 }
+
+_fio_results_key() {
+       local job=$1
+       local key=$2
+       local resultfile=$3
+
+       jq '.jobs[] | select(.jobname == "'"$job"'") | .'"$key" "$resultfile"
+}
diff --git a/common/rc b/common/rc
index 153a32358519..91972d7b0130 100644
--- a/common/rc
+++ b/common/rc
@@ -183,6 +183,14 @@ _test_dev_is_pci() {
        return 0
 }
 
+_test_dev_supports_wbt() {
+       if [[ ! -e "${TEST_DEV_SYSFS}/queue/wbt_lat_usec" ]]; then
+               SKIP_REASON="$TEST_DEV does not support wbt"
+               return 1
+       fi
+       return 0
+}
+
 _get_pci_dev_from_blkdev() {
        readlink -f "$TEST_DEV_SYSFS/device" | \
                grep -Eo '[0-9a-f]{4,5}:[0-9a-f]{2}:[0-9a-f]{2}\.[0-9a-f]' | \
diff --git a/tests/block/022 b/tests/block/022
new file mode 100755
index 000000000000..647f759e4cd0
--- /dev/null
+++ b/tests/block/022
@@ -0,0 +1,94 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0+
+# Copyright (C) 2018 Josef Bacik
+#
+# A basic test to exercise wbt and verify it's working.
+
+. tests/block/rc
+
+DESCRIPTION="run a read workload and write workload together with wbt"
+
+requires() {
+       _have_fio && _have_program jq
+}
+
+device_requires() {
+       _test_dev_supports_wbt
+}
+
+test_device() {
+       echo "Running ${TEST_NAME}"
+
+       fio_config="$TMPDIR/test.fio"
+       fio_results="$TMPDIR/results.json"
+       fio_args=("--output-format=json" "--output=$fio_results")
+
+       cat << EOF > "$fio_config"
+       [global]
+       group_reporting
+       numjobs=8
+       filename=$TEST_DEV
+       randseed=12345
+       runtime=30
+       ioengine=psync
+
+       [reads]
+       new_group
+       readwrite=randread
+
+       [writes]
+       new_group
+       readwrite=randwrite
+EOF
+
+       local wbt_setting
+       wbt_setting=$(_test_dev_queue_get wbt_lat_usec)
+
+       _test_dev_queue_set wbt_lat_usec 0
+
+       # Run just the reads to get a baseline read latency for this workload
+       if ! fio "${fio_args[@]}" "$fio_config"; then
+               echo "fio exited with status $?"
+               return 1
+       fi
+
+       local avg_lat
+       avg_lat=$(_fio_results_key reads read.lat_ns.mean "$fio_results")
+       avg_lat=$(echo "$avg_lat" | cut -d . -f 1)
+
+       echo "avg latency $avg_lat" >> "$FULL"
+
+       # WBT isn't immediate, it requires missing latency targets before it
+       # starts to clamp down on writes, so give ourselves a little wiggle room
+       # to make sure our read latencies are still protected.
+       local thresh=$((avg_lat - avg_lat * 15 / 100))
+
+       echo "threshold is $thresh" >> "$FULL"
+
+       # Fast enough disk means we may not throttle writes, so set the
+       # threshold to something stupid low so we can verify wbt is doing
+       # something.  Otherwise the defaults will be fine for spinning rust.
+       if [[ $(_test_dev_queue_get rotational) -eq "0" ]]; then
+               _test_dev_queue_set wbt_lat_usec 1
+       else
+               _test_dev_queue_set wbt_lat_usec "$wbt_setting"
+       fi
+
+       if ! fio "${fio_args[@]}" "$fio_config"; then
+               echo "fio exited with status $?"
+               return 1
+       fi
+       _test_dev_queue_set wbt_lat_usec "$wbt_setting"
+
+       avg_lat=$(_fio_results_key reads read.lat_ns.mean "$fio_results")
+       avg_lat=$(echo "$avg_lat" | cut -d . -f 1)
+       echo "avg latency contended is $avg_lat" >> "$FULL"
+
+       # Verify we are at least somewhat protected now
+       if [[ $avg_lat -gt $thresh ]]; then
+               echo "Read latency too high, wbt not working?"
+               return 1
+       fi
+
+       echo "Test complete"
+}
diff --git a/tests/block/022.out b/tests/block/022.out
new file mode 100644
index 000000000000..14d43cb1c828
--- /dev/null
+++ b/tests/block/022.out
@@ -0,0 +1,2 @@
+Running block/022
+Test complete
diff --git a/tests/block/026 b/tests/block/026
index 88113a99bd28..8b18e6314d5e 100644
--- a/tests/block/026
+++ b/tests/block/026
@@ -14,21 +14,13 @@ requires() {
                _have_program jq
 }
 
-fio_results_key() {
-       local job=$1
-       local key=$2
-       local resultfile=$3
-
-       jq '.jobs[] | select(.jobname == "'"$job"'") | .'"$key" "$resultfile"
-}
-
 sum_read_write_bytes() {
        local job=$1
        local resultfile=$2
        local readbytes writebytes
 
-       readbytes=$(fio_results_key "$job" read.io_bytes "$resultfile")
-       writebytes=$(fio_results_key "$job" write.io_bytes "$resultfile")
+       readbytes=$(_fio_results_key "$job" read.io_bytes "$resultfile")
+       writebytes=$(_fio_results_key "$job" write.io_bytes "$resultfile")
        echo $((readbytes + writebytes))
 }
 
-- 
2.14.3

Reply via email to