Skip to content

Commit 4daeb94

Browse files
committed
io_u: make rate-submit in inline mode even
In `inline` submit mode, threads wait until all previous IOs finish upon reaching rate limits, which may exceed the expected wait time and result in batch or uneven submissions. Handle completion events in usec_sleep() when necessary and no longer call io_u_quiesce() before sleeping in rate_ddir() to achieve smoother fix-rate submission as in `offload` mode. Signed-off-by: wanghonghao <[email protected]>
1 parent 4eef23f commit 4daeb94

File tree

5 files changed

+37
-24
lines changed

5 files changed

+37
-24
lines changed

backend.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ static void cleanup_pending_aio(struct thread_data *td)
233233
/*
234234
* get immediately available events, if any
235235
*/
236-
r = io_u_queued_complete(td, 0);
236+
r = io_u_queued_complete(td, 0, NULL);
237237

238238
/*
239239
* now cancel remaining active events
@@ -252,7 +252,7 @@ static void cleanup_pending_aio(struct thread_data *td)
252252
}
253253

254254
if (td->cur_depth)
255-
r = io_u_queued_complete(td, td->cur_depth);
255+
r = io_u_queued_complete(td, td->cur_depth, NULL);
256256
}
257257

258258
/*
@@ -281,7 +281,7 @@ static bool fio_io_sync(struct thread_data *td, struct fio_file *f)
281281
switch (ret) {
282282
case FIO_Q_QUEUED:
283283
td_io_commit(td);
284-
if (io_u_queued_complete(td, 1) < 0)
284+
if (io_u_queued_complete(td, 1, NULL) < 0)
285285
return true;
286286
break;
287287
case FIO_Q_COMPLETED:
@@ -433,7 +433,7 @@ static int wait_for_completions(struct thread_data *td, struct timespec *time)
433433
fio_gettime(time, NULL);
434434

435435
do {
436-
ret = io_u_queued_complete(td, min_evts);
436+
ret = io_u_queued_complete(td, min_evts, NULL);
437437
if (ret < 0)
438438
break;
439439
} while (full && (td->cur_depth > td->o.iodepth_low));
@@ -753,7 +753,7 @@ static void do_verify(struct thread_data *td, uint64_t verify_bytes)
753753
min_events = td->cur_depth;
754754

755755
if (min_events)
756-
ret = io_u_queued_complete(td, min_events);
756+
ret = io_u_queued_complete(td, min_events, NULL);
757757
} else
758758
cleanup_pending_aio(td);
759759

@@ -1175,7 +1175,7 @@ static void do_io(struct thread_data *td, uint64_t *bytes_done)
11751175
i = td->cur_depth;
11761176

11771177
if (i) {
1178-
ret = io_u_queued_complete(td, i);
1178+
ret = io_u_queued_complete(td, i, NULL);
11791179
if (td->o.fill_device &&
11801180
(td->error == ENOSPC || td->error == EDQUOT))
11811181
td->error = 0;

io_u.c

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -653,7 +653,7 @@ int io_u_quiesce(struct thread_data *td)
653653
td_io_commit(td);
654654

655655
while (td->io_u_in_flight) {
656-
ret = io_u_queued_complete(td, 1);
656+
ret = io_u_queued_complete(td, 1, NULL);
657657
if (ret > 0)
658658
completed += ret;
659659
else if (ret < 0)
@@ -709,24 +709,17 @@ static enum fio_ddir rate_ddir(struct thread_data *td, enum fio_ddir ddir)
709709
} else
710710
usec = td->rate_next_io_time[ddir] - now;
711711

712-
if (td->o.io_submit_mode == IO_MODE_INLINE)
713-
io_u_quiesce(td);
714-
715712
if (td->o.timeout && ((usec + now) > td->o.timeout)) {
716713
/*
717714
* check if the usec is capable of taking negative values
718715
*/
719-
if (now > td->o.timeout) {
720-
ddir = DDIR_TIMEOUT;
721-
return ddir;
716+
if (now < td->o.timeout) {
717+
usec_sleep(td, td->o.timeout - now);
722718
}
723-
usec = td->o.timeout - now;
724-
}
725-
usec_sleep(td, usec);
726-
727-
now = utime_since_now(&td->epoch);
728-
if ((td->o.timeout && (now > td->o.timeout)) || td->terminate)
729719
ddir = DDIR_TIMEOUT;
720+
} else {
721+
usec_sleep(td, usec);
722+
}
730723

731724
return ddir;
732725
}
@@ -2251,10 +2244,9 @@ int io_u_sync_complete(struct thread_data *td, struct io_u *io_u)
22512244
/*
22522245
* Called to complete min_events number of io for the async engines.
22532246
*/
2254-
int io_u_queued_complete(struct thread_data *td, int min_evts)
2247+
int io_u_queued_complete(struct thread_data *td, int min_evts, struct timespec *tvp)
22552248
{
22562249
struct io_completion_data icd;
2257-
struct timespec *tvp = NULL;
22582250
int ret;
22592251
struct timespec ts = { .tv_sec = 0, .tv_nsec = 0, };
22602252

io_u.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ extern void put_io_u(struct thread_data *, struct io_u *);
155155
extern void clear_io_u(struct thread_data *, struct io_u *);
156156
extern void requeue_io_u(struct thread_data *, struct io_u **);
157157
extern int __must_check io_u_sync_complete(struct thread_data *, struct io_u *);
158-
extern int __must_check io_u_queued_complete(struct thread_data *, int);
158+
extern int __must_check io_u_queued_complete(struct thread_data *, int, struct timespec *);
159159
extern void io_u_queued(struct thread_data *, struct io_u *);
160160
extern int io_u_quiesce(struct thread_data *);
161161
extern void io_u_log_error(struct thread_data *, struct io_u *);

rate-submit.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ static int io_workqueue_fn(struct submit_worker *sw,
8181
ret = td_io_queue(td, io_u);
8282
if (ret != FIO_Q_BUSY)
8383
break;
84-
ret = io_u_queued_complete(td, 1);
84+
ret = io_u_queued_complete(td, 1, NULL);
8585
if (ret > 0)
8686
td->cur_depth -= ret;
8787
else if (ret < 0)
@@ -103,7 +103,7 @@ static int io_workqueue_fn(struct submit_worker *sw,
103103
else
104104
min_evts = 0;
105105

106-
ret = io_u_queued_complete(td, min_evts);
106+
ret = io_u_queued_complete(td, min_evts, NULL);
107107
if (ret > 0)
108108
td->cur_depth -= ret;
109109
}

time.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,27 @@ uint64_t usec_sleep(struct thread_data *td, unsigned long usec)
5555
struct timespec tv;
5656
uint64_t t = 0;
5757

58+
if (td->o.io_submit_mode == IO_MODE_INLINE) {
59+
struct timespec ts;
60+
int err = 0;
61+
62+
fio_gettime(&tv, NULL);
63+
if (td->io_u_queued || td->cur_depth)
64+
td_io_commit(td);
65+
66+
while ((t = utime_since_now(&tv)) < usec &&
67+
td->io_u_in_flight && err == 0) {
68+
ts.tv_sec = (usec - t) / 1000000;
69+
ts.tv_nsec = (usec - t) % 1000000 * 1000;
70+
err = io_u_queued_complete(td, 1, &ts);
71+
}
72+
73+
if (td->flags & TD_F_REGROW_LOGS)
74+
regrow_logs(td);
75+
76+
usec = t < usec ? usec - t : 0;
77+
}
78+
5879
do {
5980
unsigned long ts = usec;
6081

0 commit comments

Comments
 (0)