@@ -3,7 +3,9 @@
CFLAGS += -O3 -Wl,-no-as-needed -Wall -I $(top_srcdir)
LDLIBS += -lpthread -lm -luring
-TEST_PROGS := test_null_01.sh
+TEST_PROGS := test_generic_01.sh
+
+TEST_PROGS += test_null_01.sh
TEST_PROGS += test_loop_01.sh
TEST_PROGS += test_loop_02.sh
TEST_PROGS += test_loop_03.sh
@@ -3,6 +3,26 @@
UBLK_SKIP_CODE=4
+_have_program() {
+ if command -v "$1" >/dev/null 2>&1; then
+ return 0
+ fi
+ return 1
+}
+
+_get_disk_dev_t() {
+ local dev_id=$1
+ local dev
+ local major
+ local minor
+
+ dev=/dev/ublkb"${dev_id}"
+ major=$(stat -c '%Hr' "$dev")
+ minor=$(stat -c '%Lr' "$dev")
+
+ echo $(( (major & 0xfff) << 20 | (minor & 0xfffff) ))
+}
+
_create_backfile() {
local my_size=$1
local my_file
@@ -121,6 +141,7 @@ _check_add_dev()
_cleanup_test() {
"${UBLK_PROG}" del -a
+ rm -f "$UBLK_TMP"
}
_have_feature()
@@ -216,6 +237,7 @@ _ublk_test_top_dir()
cd "$(dirname "$0")" && pwd
}
+UBLK_TMP=$(mktemp ublk_test_XXXXX)
UBLK_PROG=$(_ublk_test_top_dir)/kublk
UBLK_TEST_QUIET=1
UBLK_TEST_SHOW_RESULT=1
new file mode 100755
@@ -0,0 +1,44 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+. "$(cd "$(dirname "$0")" && pwd)"/test_common.sh
+
+TID="generic_01"
+ERR_CODE=0
+
+if ! _have_program bpftrace; then
+ exit "$UBLK_SKIP_CODE"
+fi
+
+_prep_test "null" "sequential io order"
+
+dev_id=$(_add_ublk_dev -t null)
+_check_add_dev $TID $?
+
+dev_t=$(_get_disk_dev_t "$dev_id")
+bpftrace trace/seq_io.bt "$dev_t" "W" 1 > "$UBLK_TMP" 2>&1 &
+btrace_pid=$!
+sleep 2
+
+if ! kill -0 "$btrace_pid" > /dev/null 2>&1; then
+ _cleanup_test "null"
+ exit "$UBLK_SKIP_CODE"
+fi
+
+# run fio over this ublk disk
+fio --name=write_seq \
+ --filename=/dev/ublkb"${dev_id}" \
+ --ioengine=libaio --iodepth=16 \
+ --rw=write \
+ --size=512M \
+ --direct=1 \
+ --bs=4k > /dev/null 2>&1
+ERR_CODE=$?
+kill "$btrace_pid"
+wait
+if grep -q "io_out_of_order" "$UBLK_TMP"; then
+ cat "$UBLK_TMP"
+ ERR_CODE=255
+fi
+_cleanup_test "null"
+_show_result $TID $ERR_CODE
new file mode 100644
@@ -0,0 +1,25 @@
+/*
+ $1: dev_t
+ $2: RWBS
+ $3: strlen($2)
+*/
+BEGIN {
+ @last_rw[$1, str($2)] = 0;
+}
+tracepoint:block:block_rq_complete
+{
+ $dev = $1;
+ if ((int64)args.dev == $1 && !strncmp(args.rwbs, str($2), $3)) {
+ $last = @last_rw[$dev, str($2)];
+ if ((uint64)args.sector != $last) {
+ printf("io_out_of_order: exp %llu actual %llu\n",
+ args.sector, $last);
+ }
+ @last_rw[$dev, str($2)] = (args.sector + args.nr_sector);
+ }
+ @ios = count();
+}
+
+END {
+ clear(@last_rw);
+}
block layer, ublk and io_uring might re-order IO in the past - plug - queue ublk io command via task work Add one test for verifying if sequential WRITE IO is dispatched in order. - null target is taken, so we can just observe io order from `tracepoint:block:block_rq_complete` which represents the dispatch order - WRITE IO is taken because READ may come from system-wide utility Cc: Uday Shankar <ushankar@purestorage.com> Signed-off-by: Ming Lei <ming.lei@redhat.com> --- tools/testing/selftests/ublk/Makefile | 4 +- tools/testing/selftests/ublk/test_common.sh | 22 ++++++++++ .../testing/selftests/ublk/test_generic_01.sh | 44 +++++++++++++++++++ tools/testing/selftests/ublk/trace/seq_io.bt | 25 +++++++++++ 4 files changed, 94 insertions(+), 1 deletion(-) create mode 100755 tools/testing/selftests/ublk/test_generic_01.sh create mode 100644 tools/testing/selftests/ublk/trace/seq_io.bt