axboe / fio

Flexible I/O Tester
GNU General Public License v2.0
5.28k stars 1.26k forks source link

rw=randread:N and rw_sequencer=sequential, do not generate random offset every N I/Os from the beginning #1223

Closed Stan-He closed 1 year ago

Stan-He commented 3 years ago

Please acknowledge the following before creating a ticket

Description of the bug: when using the config rw=randread:8 and rw_sequencer=sequential I expect fio will generate 8 sequential I/O s before switch to another random offset but at first, fio will generate only 7 sequential I/Os then switch to new random offset

After study the source code,I think the root cause may be in this function : get_next_offset and I attach the diff patch here, please check

diff --git a/io_u.c b/io_u.c
index b421a579..9c8cb0ad 100644
--- a/io_u.c
+++ b/io_u.c
@@ -484,9 +484,9 @@ static int get_next_offset(struct thread_data *td, struct io_u *io_u,

        assert(ddir_rw(ddir));

-       if (td->o.ddir_seq_nr && !--td->ddir_seq_nr) {
+       if (td->o.ddir_seq_nr && !td->ddir_seq_nr--) {
                rw_seq_hit = 1;
-               td->ddir_seq_nr = td->o.ddir_seq_nr;
+               td->ddir_seq_nr = td->o.ddir_seq_nr-1;
        }

        if (get_next_block(td, io_u, ddir, rw_seq_hit, is_random))

Environment: CentOS Linux release 8.0.1905 (Core) 4.18.0-80.el8.x86_64

fio version: fio version commit 14691a4df98b85621b07dd2bdc0f0a960acbb8ba

Reproduction steps

use the jobfile below and execute with option --debug=io,random

[global]
ioengine=libaio
iodepth=8
randrepeat=0
rw=randread:8
rw_sequencer=sequential

[test]
size=1G
bs=128k
filename=/dev/nvme0n1
sitsofe commented 3 years ago

@Stan-He This fix looks correct - would you like to work up a pull request?

ankit-sam commented 1 year ago

Hi @Stan-He, I was looking at this issue and saw that you mentioned

I expect fio will generate 8 sequential I/O s before switch to another random offset but at first, fio will generate only 7 sequential I/Os then switch to new random offset

As per the fio man page for rw_sequencer=sequential (fio.1)

If you append e.g. 8 to randread, you would get a new random offset for every 8 I/Os. The result would be a seek for only every 8 I/Os, instead of for every I/O.

It seems to me that this behavior is correct, we are getting a random offset for every 8 I/O's i.e. 1 random offset and 7 sequential offset. It also mentions that fio will seek for random offset once in every 8 I/O's. Perhaps we should phrase this in a better way to avoid any confusion.