Skip to content

Commit 3a0e8dd

Browse files
dmitry-fomichevaxboe
authored andcommitted
backend: correctly handle rate_iops combined with bssplit
Currently, rate_iops does not produce the expected I/O rate with workloads that use 'bssplit' option. Consider the following example configuration - [global] direct=1 time_based runtime=30s ioengine=io_uring thread=1 [bssplit_rate_iops_repro] filename=/dev/sdX rw=randread iodepth=8 bs=64K rate_iops=50 This works correctly and ~50 IOPS I/O rate is logged during the run. If we replace 'bs=64K' with the following bssplit option - bssplit=32ki/20:64ki/40:256ki/10:512ki/25:1mi/5 in the configuration above, then some incorrect (much lower) IOPS values are observed to be in effect at run time. This problem happens because fio, in order to derive the required I/O rate from 'rate_iops' value provided by the user, simply multiplies the IOPS value by the minimum block size (min_bs). Once bps I/O rate is calculated this way, the processing for 'rate' and 'rate_iops' becomes identical. This works if the I/O issued has the uniform min_bs, as in case of using 'bs=64K'. However, with 'bssplit' option in effect, fio may issue I/O with sizes that are much different from min_bs. Yet the code in usec_for_io() currently always calculates I/O issue delays based on min_bs leading to incorrect IOPS being produced. Fix this by modifying usec_for_io() function to check for bssplit+rate_iops being in effect. For this case, derive the IOPS rate from bps 'rate' member of thread data and then calculate the delay to the next I/O using the IOPS value, not the bps rate. Signed-off-by: Dmitry Fomichev <dmitry.fomichev@wdc.com> Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Link: https://patch.msgid.link/20260310205804.477935-1-dmitry.fomichev@wdc.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent 6d7eba0 commit 3a0e8dd

File tree

1 file changed

+19
-3
lines changed

1 file changed

+19
-3
lines changed

backend.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -844,15 +844,31 @@ static long long usec_for_io(struct thread_data *td, enum fio_ddir ddir)
844844
}
845845
td->last_usec[ddir] += val;
846846
return td->last_usec[ddir];
847-
} else if (bps) {
847+
}
848+
849+
if (!bps)
850+
return 0;
851+
852+
/*
853+
* For rate_iops option combined with bssplit, recover
854+
* the user provided IOPS value and calculate the I/O delay
855+
* based on this value, not on bps.
856+
*/
857+
if (!td->o.rate[ddir] && td->o.bssplit_nr[ddir]) {
858+
uint64_t iops = bps / td->o.min_bs[ddir];
859+
860+
if (!iops)
861+
return 0;
862+
863+
td->last_usec[ddir] += (int64_t)(1000000 / iops);
864+
return td->last_usec[ddir];
865+
} else {
848866
uint64_t bytes = td->rate_io_issue_bytes[ddir];
849867
uint64_t secs = bytes / bps;
850868
uint64_t remainder = bytes % bps;
851869

852870
return remainder * 1000000 / bps + secs * 1000000;
853871
}
854-
855-
return 0;
856872
}
857873

858874
static void init_thinktime(struct thread_data *td)

0 commit comments

Comments
 (0)