diff mbox series

blktests: add a test for wbt

Message ID 20181212213824.26958-1-josef@toxicpanda.com (mailing list archive)
State New, archived
Headers show
Series blktests: add a test for wbt | expand

Commit Message

Josef Bacik Dec. 12, 2018, 9:38 p.m. UTC
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 <josef@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

Comments

Omar Sandoval Dec. 19, 2018, 12:20 a.m. UTC | #1
On Wed, Dec 12, 2018 at 04:38:24PM -0500, Josef Bacik wrote:
> 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 <josef@toxicpanda.com>

Similar to the io.latency test. Test itself looks fine, but sometimes
fails with "Read latency too high, wbt not working?". Maybe these tests
just aren't well suited for running in QEMU?
diff mbox series

Patch

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))
 }