Fix "verify bad_hdr rand_seed" for requeued I/Os
authorHorshack <horshack@live.com>
Sun, 26 Feb 2023 15:12:05 +0000 (10:12 -0500)
committerHorshack <horshack@live.com>
Mon, 27 Feb 2023 15:08:38 +0000 (10:08 -0500)
On configurations that can cause I/Os to be internally requeued from
FIO_Q_BUSY such as '--iodepth_batch_complete_max', and the workload has
verify enabled, the subsequent verification of the data fails with a bad
verify rand_seed because the pattern for the I/O is generated twice for
the same I/O, causing the seed to become out of sync when the verify is
later performed. The seed is generate twice because do_io() handles the
I/O twice, first when it originates the I/O and again when it later gets
the same I/O back from get_io_u() after it's is pulled from the requeue
list, which is where the first submission landed due to the workload
reaching '--iodepth_batch_complete_max'.

The fix is for do_io() to track when it has generated the verify pattern
for an I/O via a new io_u flag 'IO_U_F_PATTERN_DONE', avoiding a second
call to populate_verify_io_u() when that flag is detected.

Link: https://github.com/axboe/fio/issues/1526
Signed-off-by: Adam Horshack (horshack@live.com)
backend.c
io_u.c
io_u.h

index f494c831558cb5054534e2b6b165f5af2ff16f99..975ef48938c2badc50bed84d276ffc5c8f348f1e 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -1040,8 +1040,11 @@ static void do_io(struct thread_data *td, uint64_t *bytes_done)
                }
 
                if (io_u->ddir == DDIR_WRITE && td->flags & TD_F_DO_VERIFY) {
-                       io_u->numberio = td->io_issues[io_u->ddir];
-                       populate_verify_io_u(td, io_u);
+                       if (!(io_u->flags & IO_U_F_PATTERN_DONE)) {
+                               io_u_set(td, io_u, IO_U_F_PATTERN_DONE);
+                               io_u->numberio = td->io_issues[io_u->ddir];
+                               populate_verify_io_u(td, io_u);
+                       }
                }
 
                ddir = io_u->ddir;
diff --git a/io_u.c b/io_u.c
index eb617e649c1df82dba42259361cd36f3a32e7796..0b2754f1e9441f8d0ba5a8ea060ad7760fa76c90 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -2004,7 +2004,7 @@ static void io_completed(struct thread_data *td, struct io_u **io_u_ptr,
        dprint_io_u(io_u, "complete");
 
        assert(io_u->flags & IO_U_F_FLIGHT);
-       io_u_clear(td, io_u, IO_U_F_FLIGHT | IO_U_F_BUSY_OK);
+       io_u_clear(td, io_u, IO_U_F_FLIGHT | IO_U_F_BUSY_OK | IO_U_F_PATTERN_DONE);
 
        /*
         * Mark IO ok to verify
diff --git a/io_u.h b/io_u.h
index 206e24fee09ec955a05220203576a6e9c03220d3..9b5d697d94deab090e059e82c8b7f334b6102446 100644 (file)
--- a/io_u.h
+++ b/io_u.h
@@ -21,6 +21,7 @@ enum {
        IO_U_F_TRIMMED          = 1 << 5,
        IO_U_F_BARRIER          = 1 << 6,
        IO_U_F_VER_LIST         = 1 << 7,
+       IO_U_F_PATTERN_DONE = 1 << 8,
 };
 
 /*