io_uring, io_uring_cmd, and libaio record issue_time inside the ioengine
code when their commit functions are called. So we don't need to record
issue_time again for these ioengines in td_io_queue.
If we do fill issue_time twice, then mean(slat) + mean(clat) !=
mean(lat):
user@ubuntu:~/fio-dev$ fio-canonical/fio --name=test --ioengine=io_uring --number_ios=1 --rw=randread --size=1M
test: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=io_uring, iodepth=1
fio-3.30-48-g26fa
Starting 1 process
test: (groupid=0, jobs=1): err= 0: pid=172145: Mon Jun 6 16:12:42 2022
read: IOPS=1000, BW=4000KiB/s (4096kB/s)(4096B/1msec)
slat (nsec): min=61424, max=61424, avg=61424.00, stdev= 0.00
clat (nsec): min=242709, max=242709, avg=242709.00, stdev= 0.00
lat (nsec): min=308346, max=308346, avg=308346.00, stdev= 0.00
61424 + 242709 = 304133 != 308346
If we fill issue_time only once, then the equality will hold (as it
should):
user@ubuntu:~/fio-dev$ fio-latency/fio --name=test --ioengine=io_uring --number_ios=1 --rw=randread --size=1M
test: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=io_uring, iodepth=1
fio-3.30-48-g26fa-dirty
Starting 1 process
test: (groupid=0, jobs=1): err= 0: pid=172220: Mon Jun 6 16:12:47 2022
read: IOPS=1000, BW=4000KiB/s (4096kB/s)(4096B/1msec)
slat (nsec): min=53701, max=53701, avg=53701.00, stdev= 0.00
clat (nsec): min=259566, max=259566, avg=259566.00, stdev= 0.00
lat (nsec): min=313267, max=313267, avg=313267.00, stdev= 0.00
53701 + 259566 = 313267
Signed-off-by: Vincent Fu <vincent.fu@samsung.com>
Link: https://lore.kernel.org/r/20220614155822.307771-3-vincent.fu@samsung.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
static struct ioengine_ops ioengine_uring = {
.name = "io_uring",
.version = FIO_IOOPS_VERSION,
- .flags = FIO_ASYNCIO_SYNC_TRIM | FIO_NO_OFFLOAD,
+ .flags = FIO_ASYNCIO_SYNC_TRIM | FIO_NO_OFFLOAD |
+ FIO_ASYNCIO_SETS_ISSUE_TIME,
.init = fio_ioring_init,
.post_init = fio_ioring_post_init,
.io_u_init = fio_ioring_io_u_init,
static struct ioengine_ops ioengine_uring_cmd = {
.name = "io_uring_cmd",
.version = FIO_IOOPS_VERSION,
- .flags = FIO_ASYNCIO_SYNC_TRIM | FIO_NO_OFFLOAD | FIO_MEMALIGN | FIO_RAWIO,
+ .flags = FIO_ASYNCIO_SYNC_TRIM | FIO_NO_OFFLOAD |
+ FIO_MEMALIGN | FIO_RAWIO |
+ FIO_ASYNCIO_SETS_ISSUE_TIME,
.init = fio_ioring_init,
.post_init = fio_ioring_cmd_post_init,
.io_u_init = fio_ioring_io_u_init,
FIO_STATIC struct ioengine_ops ioengine = {
.name = "libaio",
.version = FIO_IOOPS_VERSION,
- .flags = FIO_ASYNCIO_SYNC_TRIM,
+ .flags = FIO_ASYNCIO_SYNC_TRIM |
+ FIO_ASYNCIO_SETS_ISSUE_TIME,
.init = fio_libaio_init,
.post_init = fio_libaio_post_init,
.prep = fio_libaio_prep,
if (!td_ioengine_flagged(td, FIO_SYNCIO) &&
!async_ioengine_sync_trim(td, io_u)) {
- if (fio_fill_issue_time(td))
+ if (fio_fill_issue_time(td) &&
+ !td_ioengine_flagged(td, FIO_ASYNCIO_SETS_ISSUE_TIME))
fio_gettime(&io_u->issue_time, NULL);
/*
FIO_ASYNCIO_SYNC_TRIM
= 1 << 14, /* io engine has async ->queue except for trim */
FIO_NO_OFFLOAD = 1 << 15, /* no async offload */
+ FIO_ASYNCIO_SETS_ISSUE_TIME
+ = 1 << 16, /* async ioengine with commit function that sets issue_time */
};
/*