]> www.infradead.org Git - users/sagi/blktests.git/commitdiff
Add a test for the blk-mq direct issue corruption corruption
authorOmar Sandoval <osandov@fb.com>
Thu, 20 Dec 2018 22:12:03 +0000 (14:12 -0800)
committerOmar Sandoval <osandov@fb.com>
Thu, 20 Dec 2018 22:25:43 +0000 (14:25 -0800)
This is based on a fio job from Jens with the following description:

  This job file does:

  One write/read verify set, using 256M of files, each 1M. The reader
  part runs 16 times, and in two jobs, while the next write/read verify
  set starts. This set is much larger, it's mainly meant to generate
  write based IO with frequent fsyncs. The fsyncs are key, as they do
  not queue on SATA. This means that the other reads (or writes) can
  get a BUSY condition off direct issue, and with lots of other IO
  going, stay around for a longer time before getting re-issued. This
  increases the chances of a merge happening before they are re-issued.

  I cannot reproduce this on bare metal, tried a lot of different
  boxes. What does work reliably for me is a qemu setup, with 1 CPU,
  and limited to 400M of RAM. The drive used for testing should be
  the following:

  -drive file=scsi.raw,media=disk,if=ide

  created with: qemu-img create -f raw scsi.raw 10G

  The machine type used with qemu was -machine q35,accel=kvm

  Once booted, ensure that sda (if that's the drive above) is not using
  an IO scheduler:

  echo none > /sys/block/sda/queue/scheduler

  Then just normally mkfs + mount the device, and run this job file in
  the mount point.

  Thanks to Lukáš Krejčí for describing how he reproduced it, the qemu
  setup above is directly based on his description.

I.e., it only reproduces the bug under certain conditions, but it's
still valuable enough to have a fio verify test.

Signed-off-by: Omar Sandoval <osandov@fb.com>
tests/block/022 [new file with mode: 0755]
tests/block/022.out [new file with mode: 0644]

diff --git a/tests/block/022 b/tests/block/022
new file mode 100755 (executable)
index 0000000..49cf156
--- /dev/null
@@ -0,0 +1,95 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0+
+# Copyright (C) 2018 Omar Sandoval
+#
+# Run fio in verify mode with a mixed read/write/fsync buffered workload on
+# ext4. This is based on the reproducer for commit ffe81d45322c ("blk-mq: fix
+# corruption with direct issue"), but it is very timing-sensitive. Running it
+# in QEMU with the following options tends to reproduce the original bug:
+# -machine q35,accel=kvm -cpu 1 -m 400M -drive file=$IMG,media=disk,if=ide
+# Thanks to Lukáš Krejčí for providing this QEMU setup.
+
+. tests/block/rc
+
+DESCRIPTION="verify reads, writes, and flushes through a filesystem"
+TIMED=1
+
+requires() {
+       _have_fio && _have_program mkfs.ext4 && _have_modules ext4
+}
+
+test_device() {
+       echo "Running ${TEST_NAME}"
+
+       : "${TIMEOUT:=30}"
+
+       if grep -qw none "${TEST_DEV_SYSFS}/queue/scheduler"; then
+               _test_dev_queue_set scheduler none
+       fi
+
+       mkfs.ext4 -Fq "$TEST_DEV" || return 1
+       mkdir -p "$TMPDIR/mnt" || return 1
+       mount "$TEST_DEV" "$TMPDIR/mnt" || return 1
+
+       cat << EOF > "$TMPDIR/test.fio"
+[global]
+bs=4k
+buffered=1
+filesize=1m
+file_service_type=random
+verify=crc32c
+refill_buffers=1
+randseed=89
+openfiles=1000
+exitall_on_error=1
+cpus_allowed=0
+
+[write1]
+filename_format=test1.\$filenum
+nr_files=256
+rw=write
+do_verify=0
+
+[read1]
+wait_for=write1
+filename_format=test1.\$filenum
+nr_files=256
+invalidate=1
+rw=read
+do_verify=1
+loops=16
+
+[read1-again]
+wait_for=write1
+filename_format=test1.\$filenum
+nr_files=256
+invalidate=1
+rw=read
+do_verify=1
+loops=16
+
+[write2]
+wait_for=write1
+filename_format=test2.\$filenum
+nr_files=768
+rw=write
+do_verify=0
+fsync=8
+
+[read2]
+wait_for=write2
+filename_format=test2.\$filenum
+nr_files=768
+invalidate=1
+rw=read
+do_verify=1
+EOF
+
+       pushd "$TMPDIR/mnt" > /dev/null || return 1
+       _run_fio "$TMPDIR/test.fio"
+       popd > /dev/null || return 1
+
+       umount "$TMPDIR/mnt"
+
+       echo "Test complete"
+}
diff --git a/tests/block/022.out b/tests/block/022.out
new file mode 100644 (file)
index 0000000..14d43cb
--- /dev/null
@@ -0,0 +1,2 @@
+Running block/022
+Test complete