Skip to contentSkip to conversation

Recent changes (master)

PATCH Jens Axboe 1 participant 1 message Jun 11

lore
Share & tools
lore

Jens Axboe

author
#0 lore raw

The following changes since commit f055bacb90990b96fe9940579b3f7eda3515679f:

t/nvmept_write_mode: fix fio path (2026-06-10 00:21:19 +0000)

are available in the Git repository at:

git://git.kernel.dk/fio.git master

for you to fetch changes up to bd11387aba55e9dc58c0127437c8c6982e6ac32f:

ci: skip new write uncorrectable tests on QEMU (2026-06-10 22:28:50 +0000)

----------------------------------------------------------------
Minwoo Im (3):
io_uring_cmd: support mixed write_mode with ratio
io_u: add zeroed, errored flags to @io_u for verify t/nvmept_write_mode: add multiple write_mode tests

Vincent Fu (7):
Merge branch 'io_uring/multiple-write-modes' of https://github.com/minwooim/fio
engines/io_uring_cmd: debug print for write mode
verify: debug print for verifying write zeroes t/nvmept_write_mode: check write mode splits
t/nvmept_write_mode: check verify job
t/nvmept_write_mode: improve formatting
ci: skip new write uncorrectable tests on QEMU

 .github/workflows/qemu.yml        |   2 +-
 HOWTO.rst                         |   6 +
 engines/io_uring.c                | 261 +++++++++++++++++++++++++++-----
 examples/uring-cmd-write-mode.fio |  21 +++
 examples/uring-cmd-write-mode.png | Bin 0 -> 41207 bytes
 fio.1                             |   6 +
 fio.h                             |   1 +
 io_u.c                            |  11 +-
 io_u.h                            |   2 +
 iolog.c                           |   5 +
 iolog.h                           |   2 +
 t/nvmept_write_mode.py            | 303 ++++++++++++++++++++++++++++++++++++--
 verify.c                          |  25 +++-
 13 files changed, 590 insertions(+), 55 deletions(-)
 create mode 100644 examples/uring-cmd-write-mode.fio
 create mode 100644 examples/uring-cmd-write-mode.png

---

Diff of recent changes:

.github/workflows/qemu.yml +1 -1
index ba0a00ac..451ecd42 100644
@@ -18,7 +18,7 @@ jobs:
               -device nvme,id=nvme0,serial=deadbeef
               -drive id=nvm-0,file=nvme0.img,format=raw,if=none,discard=unmap,media=disk
               -device nvme-ns,id=nvm-0,drive=nvm-0,bus=nvme0,nsid=1
-            test_cmd: "python3 t/run-fio-tests.py --nvmecdev /dev/ng0n1 --run-only 1014 1015 1022 -p '1022:--skip 30 31 32 33 34'"
+            test_cmd: "python3 t/run-fio-tests.py --nvmecdev /dev/ng0n1 --run-only 1014 1015 1022 -p '1022:--skip 30 31 32 33 34 40 50 51 53 70'"
             extra_pkgs: "nvme-cli"
           - config: 16-bit Guard PI tests (long)
             device: >-
HOWTO.rst +6 -0
index 63964eb9..ac570972 100644
@@ -3049,6 +3049,12 @@ with the caveat that when used on the command line, they must come after the
                 **verify**
                         Use Verify commands for write operations
 
+        Multiple modes with mix ratios can be specified using the format
+        ``mode/pct:mode/pct:...``.  Percentages must sum to 100.  If a
+        percentage is omitted, the remaining percentage is split evenly among
+        entries with no percentage specified.
+        Example: ``write/60:zeroes/30:uncor/10`` or ``write/50:zeroes/:uncor/``
+
 .. option:: verify_mode=str : [io_uring_cmd]
 
         Specifies the type of command to be used in the verification phase.  Defaults to 'read'.
engines/io_uring.c +223 -38

322 lines not on this page · raw message

examples/uring-cmd-write-mode.fio new file +21 -0
new file mode 100644
index 00000000..63e4c18c
@@ -0,0 +1,21 @@
+# io_uring_cmd mixed write_mode example
+#
+# Issues write, zeroes, uncor, and verify commands in a single job
+# using the ratio-based write_mode syntax:
+#
+#   write_mode=write/40:zeroes/30:uncor/20:verify/10
+#
+# Replace /dev/ng0n1 with the target nvme-ns generic character device.
+
+[global]
+filename=/dev/ng0n1
+ioengine=io_uring_cmd
+cmd_type=nvme
+size=1G
+iodepth=32
+bs=4K
+thread=1
+
+[mixed-write-modes]
+rw=write
+write_mode=write/40:zeroes/30:uncor/20:verify/10
examples/uring-cmd-write-mode.png new file binary +0 -0
new file mode 100644
index 00000000..8754c111
Binary files /dev/null and b/examples/uring-cmd-write-mode.png differ
fio.1 +6 -0
index 71a7309a..d2933a8f 100644
@@ -2835,6 +2835,12 @@ Use Write Zeroes commands for write operations
 .B verify
 Use Verify commands for write operations
 .RE
+.P
+Multiple modes with mix ratios can be specified using the format
+\fBmode/pct:mode/pct:...\fR.  Percentages must sum to 100.  If a percentage
+is omitted, the remaining percentage is split evenly among entries with no
+percentage specified.
+Example: \fBwrite/60:zeroes/30:uncor/10\fR or \fBwrite/50:zeroes/:uncor/\fR
 .RE
 .TP
 .BI (io_uring_cmd)verify_mode \fR=\fPstr
fio.h +1 -0
index 8ef3523e..b05abf77 100644
@@ -156,6 +156,7 @@ enum {
 	FIO_RAND_DEDUPE_WORKING_SET_IX,
 	FIO_RAND_FDP_OFF,
 	FIO_RAND_SPRANDOM_OFF,
+	FIO_RAND_WMODE_OFF,
 	FIO_RAND_NR_OFFS,
 };
 
io_u.c +9 -2
index 8b90dd1b..c3327f16 100644
@@ -2232,9 +2232,16 @@ static void io_completed(struct thread_data *td, struct io_u **io_u_ptr,
 				icd->error = ret;
 		}
 	} else if (io_u->error) {
+		if (!((io_u->flags & IO_U_F_ERRORED) &&
+				(io_u->flags & IO_U_F_VER_LIST))) {
 error:
-		icd->error = io_u->error;
-		io_u_log_error(td, io_u);
+			icd->error = io_u->error;
+			io_u_log_error(td, io_u);
+		} else {
+			dprint(FD_IO, "io_completed: errored io_u numberio="
+					"%"PRIu64" for verify (expected)\n",
+					io_u->numberio);
+		}
 	}
 	if (icd->error) {
 		enum error_type_bit eb = td_error_type(ddir, icd->error);
io_u.h +2 -0
index 68771eba..0f656ee0 100644
@@ -24,6 +24,8 @@ enum {
 	IO_U_F_PATTERN_DONE	= 1 << 8,
 	IO_U_F_DEVICE_ERROR	= 1 << 9,
 	IO_U_F_VER_IN_DEV	= 1 << 10, /* Verify data in device */
+	IO_U_F_ZEROED		= 1 << 11, /* Zeroed data */
+	IO_U_F_ERRORED		= 1 << 12, /* Errored offset */
 };
 
 /*
iolog.c +5 -0
index dcf6083c..df862ea6 100644
@@ -295,6 +295,11 @@ void log_io_piece(struct thread_data *td, struct io_u *io_u)
 
 	io_u->ipo = ipo;
 
+	if (io_u->flags & IO_U_F_ZEROED)
+		ipo->flags |= IP_F_ZEROED;
+	else if (io_u->flags & IO_U_F_ERRORED)
+		ipo->flags |= IP_F_ERRORED;
+
 	if (io_u_should_trim(td, io_u)) {
 		flist_add_tail(&ipo->trim_list, &td->trim_list);
 		td->trim_entries++;
iolog.h +2 -0
index b52ae87d..8730427c 100644
@@ -244,6 +244,8 @@ enum {
 	IP_F_ONLIST	= 2,
 	IP_F_TRIMMED	= 4,
 	IP_F_IN_FLIGHT	= 8,
+	IP_F_ZEROED	= 16,
+	IP_F_ERRORED	= 32,
 };
 
 /*
t/nvmept_write_mode.py +294 -9

339 lines not on this page · raw message

verify.c +20 -5
index 7237dc2c..d8312815 100644
@@ -891,25 +891,30 @@ static int mem_is_zero_slow(const void *data, size_t length, size_t *offset)
 	return !length;
 }
 
-static int verify_trimmed_io_u(struct thread_data *td, struct io_u *io_u)
+static int verify_zero(struct io_u *io_u)
 {
 	size_t offset;
 
-	if (!td->o.trim_zero)
-		return 0;
-
 	if (mem_is_zero(io_u->buf, io_u->buflen))
 		return 0;
 
 	mem_is_zero_slow(io_u->buf, io_u->buflen, &offset);
 
-	log_err("trim: verify failed at file %s offset %llu, length %llu"
+	log_err("verify failed for zeroed data at file %s offset %llu, length %llu"
 		", block offset %lu\n",
 			io_u->file->file_name, io_u->verify_offset, io_u->buflen,
 			(unsigned long) offset);
 	return EILSEQ;
 }
 
+static int verify_trimmed_io_u(struct thread_data *td, struct io_u *io_u)
+{
+	if (!td->o.trim_zero)
+		return 0;
+
+	return verify_zero(io_u);
+}
+
 static int verify_header(struct io_u *io_u, struct thread_data *td,
 			 struct verify_header *hdr, unsigned int hdr_num,
 			 unsigned int hdr_len)
@@ -1011,6 +1016,10 @@ int verify_io_u(struct thread_data *td, struct io_u **io_u_ptr)
 	if (io_u->flags & IO_U_F_TRIMMED) {
 		ret = verify_trimmed_io_u(td, io_u);
 		goto done;
+	} else if (io_u->flags & IO_U_F_ZEROED) {
+		dprint(FD_VERIFY, "verifying write zeroes command\n");
+		ret = verify_zero(io_u);
+		goto done;
 	}
 
 	hdr_inc = get_hdr_inc(td, io_u);
@@ -1451,8 +1460,14 @@ int get_next_verify(struct thread_data *td, struct io_u *io_u)
 		io_u->file = ipo->file;
 		io_u_set(td, io_u, IO_U_F_VER_LIST);
 
+		io_u_clear(td, io_u, IO_U_F_TRIMMED | IO_U_F_ZEROED | IO_U_F_ERRORED);
+
 		if (ipo->flags & IP_F_TRIMMED)
 			io_u_set(td, io_u, IO_U_F_TRIMMED);
+		else if (ipo->flags & IP_F_ZEROED)
+			io_u_set(td, io_u, IO_U_F_ZEROED);
+		else if (ipo->flags & IP_F_ERRORED)
+			io_u_set(td, io_u, IO_U_F_ERRORED);
 
 		if (!fio_file_open(io_u->file)) {
 			int r = td_io_open_file(td, io_u->file);