Switch to using our internal Tausworthe based random generator for offsets
[fio.git] / io_u.c
CommitLineData
10ba535a
JA
1#include <unistd.h>
2#include <fcntl.h>
3#include <string.h>
4#include <signal.h>
5#include <time.h>
0c6e7517 6#include <assert.h>
10ba535a
JA
7
8#include "fio.h"
5973cafb 9#include "hash.h"
4f5af7b2 10#include "verify.h"
0d29de83 11#include "trim.h"
1fbbf72e 12#include "lib/rand.h"
10ba535a 13
97601024
JA
14struct io_completion_data {
15 int nr; /* input */
97601024
JA
16
17 int error; /* output */
18 unsigned long bytes_done[2]; /* output */
19 struct timeval time; /* output */
20};
21
10ba535a
JA
22/*
23 * The ->file_map[] contains a map of blocks we have or have not done io
24 * to yet. Used to make sure we cover the entire range in a fair fashion.
25 */
aec2de20 26static int random_map_free(struct fio_file *f, const unsigned long long block)
10ba535a 27{
aec2de20
JA
28 unsigned int idx = RAND_MAP_IDX(f, block);
29 unsigned int bit = RAND_MAP_BIT(f, block);
10ba535a 30
84422acd
JA
31 dprint(FD_RANDOM, "free: b=%llu, idx=%u, bit=%u\n", block, idx, bit);
32
0ce8b119 33 return (f->file_map[idx] & (1UL << bit)) == 0;
10ba535a
JA
34}
35
df415585
JA
36/*
37 * Mark a given offset as used in the map.
38 */
9bf2061e 39static void mark_random_map(struct thread_data *td, struct io_u *io_u)
df415585 40{
2dc1bbeb 41 unsigned int min_bs = td->o.rw_min_bs;
9bf2061e 42 struct fio_file *f = io_u->file;
a00735e6 43 unsigned long long block;
3e3357b1 44 unsigned int blocks, nr_blocks;
38dad62d 45 int busy_check;
df415585 46
b9c5b644 47 block = (io_u->offset - f->file_offset) / (unsigned long long) min_bs;
c685b5b2 48 nr_blocks = (io_u->buflen + min_bs - 1) / min_bs;
3e3357b1 49 blocks = 0;
38dad62d 50 busy_check = !(io_u->flags & IO_U_F_BUSY_OK);
c685b5b2 51
3e3357b1 52 while (nr_blocks) {
df415585 53 unsigned int idx, bit;
0ce8b119 54 unsigned long mask, this_blocks;
df415585 55
1e3d53ac
JA
56 /*
57 * If we have a mixed random workload, we may
58 * encounter blocks we already did IO to.
59 */
38dad62d
JA
60 if (!busy_check) {
61 blocks = nr_blocks;
62 break;
63 }
5736c10d 64 if ((td->o.ddir_seq_nr == 1) && !random_map_free(f, block))
df415585
JA
65 break;
66
aec2de20
JA
67 idx = RAND_MAP_IDX(f, block);
68 bit = RAND_MAP_BIT(f, block);
df415585 69
0032bf9f 70 fio_assert(td, idx < f->num_maps);
df415585 71
3e3357b1
JA
72 this_blocks = nr_blocks;
73 if (this_blocks + bit > BLOCKS_PER_MAP)
74 this_blocks = BLOCKS_PER_MAP - bit;
75
da3758bf
JA
76 do {
77 if (this_blocks == BLOCKS_PER_MAP)
0ce8b119 78 mask = -1UL;
da3758bf 79 else
0ce8b119 80 mask = ((1UL << this_blocks) - 1) << bit;
da3758bf
JA
81
82 if (!(f->file_map[idx] & mask))
83 break;
84
85 this_blocks--;
86 } while (this_blocks);
87
88 if (!this_blocks)
89 break;
3e3357b1 90
3e3357b1
JA
91 f->file_map[idx] |= mask;
92 nr_blocks -= this_blocks;
93 blocks += this_blocks;
c9dd34b2 94 block += this_blocks;
df415585
JA
95 }
96
a00735e6
JA
97 if ((blocks * min_bs) < io_u->buflen)
98 io_u->buflen = blocks * min_bs;
df415585
JA
99}
100
3e3357b1
JA
101static unsigned long long last_block(struct thread_data *td, struct fio_file *f,
102 enum fio_ddir ddir)
2ba1c290
JA
103{
104 unsigned long long max_blocks;
d9dd70f7 105 unsigned long long max_size;
2ba1c290 106
ff58fced
JA
107 assert(ddir_rw(ddir));
108
d9dd70f7
JA
109 /*
110 * Hmm, should we make sure that ->io_size <= ->real_file_size?
111 */
112 max_size = f->io_size;
113 if (max_size > f->real_file_size)
114 max_size = f->real_file_size;
115
2b7a01d0 116 max_blocks = max_size / (unsigned long long) td->o.ba[ddir];
2ba1c290
JA
117 if (!max_blocks)
118 return 0;
119
67778e88 120 return max_blocks;
2ba1c290
JA
121}
122
10ba535a
JA
123/*
124 * Return the next free block in the map.
125 */
126static int get_next_free_block(struct thread_data *td, struct fio_file *f,
4ba66134 127 enum fio_ddir ddir, unsigned long long *b)
10ba535a 128{
0ce8b119 129 unsigned long long block, min_bs = td->o.rw_min_bs, lastb;
10ba535a
JA
130 int i;
131
5e0baa7f
JA
132 lastb = last_block(td, f, ddir);
133 if (!lastb)
134 return 1;
135
c685b5b2 136 i = f->last_free_lookup;
0ce8b119
JA
137 block = i * BLOCKS_PER_MAP;
138 while (block * min_bs < f->real_file_size &&
139 block * min_bs < f->io_size) {
140 if (f->file_map[i] != -1UL) {
141 block += ffz(f->file_map[i]);
142 if (block > lastb)
2ba1c290 143 break;
c685b5b2 144 f->last_free_lookup = i;
0ce8b119 145 *b = block;
10ba535a
JA
146 return 0;
147 }
148
0ce8b119 149 block += BLOCKS_PER_MAP;
10ba535a
JA
150 i++;
151 }
152
2ba1c290 153 dprint(FD_IO, "failed finding a free block\n");
10ba535a
JA
154 return 1;
155}
156
ec4015da 157static int get_next_rand_offset(struct thread_data *td, struct fio_file *f,
4ba66134 158 enum fio_ddir ddir, unsigned long long *b)
ec4015da 159{
5e0baa7f 160 unsigned long long r, lastb;
ec4015da
JA
161 int loops = 5;
162
5e0baa7f
JA
163 lastb = last_block(td, f, ddir);
164 if (!lastb)
165 return 1;
166
0ce8b119
JA
167 if (f->failed_rands >= 200)
168 goto ffz;
169
ec4015da 170 do {
2615cc4b
JA
171 if (td->o.use_os_rand) {
172 r = os_random_long(&td->random_state);
173 *b = (lastb - 1) * (r / ((unsigned long long) OS_RAND_MAX + 1.0));
174 } else {
175 r = __rand(&td->__random_state);
176 *b = (lastb - 1) * (r / ((unsigned long long) FRAND_MAX + 1.0));
177 }
178
84422acd 179 dprint(FD_RANDOM, "off rand %llu\n", r);
2615cc4b 180
2ba1c290 181
43c63a78
JA
182 /*
183 * if we are not maintaining a random map, we are done.
184 */
303032ae 185 if (!file_randommap(td, f))
0ce8b119 186 goto ret_good;
43c63a78
JA
187
188 /*
84422acd 189 * calculate map offset and check if it's free
43c63a78 190 */
aec2de20 191 if (random_map_free(f, *b))
0ce8b119 192 goto ret_good;
43c63a78 193
84422acd
JA
194 dprint(FD_RANDOM, "get_next_rand_offset: offset %llu busy\n",
195 *b);
43c63a78 196 } while (--loops);
ec4015da 197
0ce8b119
JA
198 if (!f->failed_rands++)
199 f->last_free_lookup = 0;
200
ec4015da 201 /*
43c63a78
JA
202 * we get here, if we didn't suceed in looking up a block. generate
203 * a random start offset into the filemap, and find the first free
204 * block from there.
ec4015da 205 */
43c63a78
JA
206 loops = 10;
207 do {
dc873b6f
JA
208 f->last_free_lookup = (f->num_maps - 1) *
209 (r / (OS_RAND_MAX + 1.0));
4ba66134 210 if (!get_next_free_block(td, f, ddir, b))
0ce8b119 211 goto ret;
ec4015da 212
43c63a78
JA
213 r = os_random_long(&td->random_state);
214 } while (--loops);
215
216 /*
217 * that didn't work either, try exhaustive search from the start
218 */
219 f->last_free_lookup = 0;
0ce8b119
JA
220ffz:
221 if (!get_next_free_block(td, f, ddir, b))
222 return 0;
223 f->last_free_lookup = 0;
4ba66134 224 return get_next_free_block(td, f, ddir, b);
0ce8b119
JA
225ret_good:
226 f->failed_rands = 0;
227ret:
228 return 0;
ec4015da
JA
229}
230
38dad62d
JA
231static int get_next_rand_block(struct thread_data *td, struct fio_file *f,
232 enum fio_ddir ddir, unsigned long long *b)
233{
234 if (get_next_rand_offset(td, f, ddir, b)) {
235 dprint(FD_IO, "%s: rand offset failed, last=%llu, size=%llu\n",
236 f->file_name, f->last_pos, f->real_file_size);
237 return 1;
238 }
239
240 return 0;
241}
242
243static int get_next_seq_block(struct thread_data *td, struct fio_file *f,
244 enum fio_ddir ddir, unsigned long long *b)
245{
ff58fced
JA
246 assert(ddir_rw(ddir));
247
38dad62d
JA
248 if (f->last_pos < f->real_file_size) {
249 *b = (f->last_pos - f->file_offset) / td->o.min_bs[ddir];
250 return 0;
251 }
252
253 return 1;
254}
255
256static int get_next_block(struct thread_data *td, struct io_u *io_u,
257 enum fio_ddir ddir, int rw_seq, unsigned long long *b)
258{
259 struct fio_file *f = io_u->file;
260 int ret;
261
ff58fced
JA
262 assert(ddir_rw(ddir));
263
38dad62d
JA
264 if (rw_seq) {
265 if (td_random(td))
266 ret = get_next_rand_block(td, f, ddir, b);
267 else
268 ret = get_next_seq_block(td, f, ddir, b);
269 } else {
270 io_u->flags |= IO_U_F_BUSY_OK;
271
272 if (td->o.rw_seq == RW_SEQ_SEQ) {
273 ret = get_next_seq_block(td, f, ddir, b);
274 if (ret)
275 ret = get_next_rand_block(td, f, ddir, b);
276 } else if (td->o.rw_seq == RW_SEQ_IDENT) {
277 if (f->last_start != -1ULL)
0508320e
DN
278 *b = (f->last_start - f->file_offset)
279 / td->o.min_bs[ddir];
38dad62d
JA
280 else
281 *b = 0;
282 ret = 0;
283 } else {
284 log_err("fio: unknown rw_seq=%d\n", td->o.rw_seq);
285 ret = 1;
286 }
287 }
288
289 return ret;
290}
291
10ba535a
JA
292/*
293 * For random io, generate a random new block and see if it's used. Repeat
294 * until we find a free one. For sequential io, just return the end of
295 * the last io issued.
296 */
15dc1934 297static int __get_next_offset(struct thread_data *td, struct io_u *io_u)
10ba535a 298{
9bf2061e 299 struct fio_file *f = io_u->file;
ec4015da 300 unsigned long long b;
4ba66134 301 enum fio_ddir ddir = io_u->ddir;
38dad62d 302 int rw_seq_hit = 0;
10ba535a 303
ff58fced
JA
304 assert(ddir_rw(ddir));
305
38dad62d
JA
306 if (td->o.ddir_seq_nr && !--td->ddir_seq_nr) {
307 rw_seq_hit = 1;
5736c10d 308 td->ddir_seq_nr = td->o.ddir_seq_nr;
38dad62d 309 }
211097b2 310
0508320e 311 if (get_next_block(td, io_u, ddir, rw_seq_hit, &b))
38dad62d 312 return 1;
10ba535a 313
2b7a01d0 314 io_u->offset = b * td->o.ba[ddir];
009bd847
JA
315 if (io_u->offset >= f->io_size) {
316 dprint(FD_IO, "get_next_offset: offset %llu >= io_size %llu\n",
317 io_u->offset, f->io_size);
318 return 1;
319 }
320
321 io_u->offset += f->file_offset;
2ba1c290
JA
322 if (io_u->offset >= f->real_file_size) {
323 dprint(FD_IO, "get_next_offset: offset %llu >= size %llu\n",
324 io_u->offset, f->real_file_size);
10ba535a 325 return 1;
2ba1c290 326 }
10ba535a
JA
327
328 return 0;
329}
330
15dc1934
JA
331static int get_next_offset(struct thread_data *td, struct io_u *io_u)
332{
7eb36574
JA
333 struct prof_io_ops *ops = &td->prof_io_ops;
334
335 if (ops->fill_io_u_off)
336 return ops->fill_io_u_off(td, io_u);
15dc1934
JA
337
338 return __get_next_offset(td, io_u);
339}
340
341static unsigned int __get_next_buflen(struct thread_data *td, struct io_u *io_u)
10ba535a 342{
bca4ed4d 343 const int ddir = io_u->ddir;
f3f552b9 344 unsigned int uninitialized_var(buflen);
f3059de1 345 unsigned int minbs, maxbs;
10ba535a
JA
346 long r;
347
ff58fced
JA
348 assert(ddir_rw(ddir));
349
f3059de1
JA
350 minbs = td->o.min_bs[ddir];
351 maxbs = td->o.max_bs[ddir];
352
353 if (minbs == maxbs)
354 buflen = minbs;
10ba535a
JA
355 else {
356 r = os_random_long(&td->bsrange_state);
720e84ad 357 if (!td->o.bssplit_nr[ddir]) {
f3059de1
JA
358 buflen = 1 + (unsigned int) ((double) maxbs *
359 (r / (OS_RAND_MAX + 1.0)));
360 if (buflen < minbs)
361 buflen = minbs;
5ec10eaa 362 } else {
564ca972
JA
363 long perc = 0;
364 unsigned int i;
365
720e84ad
JA
366 for (i = 0; i < td->o.bssplit_nr[ddir]; i++) {
367 struct bssplit *bsp = &td->o.bssplit[ddir][i];
564ca972
JA
368
369 buflen = bsp->bs;
370 perc += bsp->perc;
f3059de1 371 if (r <= ((OS_RAND_MAX / 100L) * perc))
564ca972
JA
372 break;
373 }
374 }
f3059de1
JA
375 if (!td->o.bs_unaligned && is_power_of_2(minbs))
376 buflen = (buflen + minbs - 1) & ~(minbs - 1);
10ba535a
JA
377 }
378
4ba66134
JA
379 if (io_u->offset + buflen > io_u->file->real_file_size) {
380 dprint(FD_IO, "lower buflen %u -> %u (ddir=%d)\n", buflen,
f3059de1
JA
381 minbs, ddir);
382 buflen = minbs;
4ba66134 383 }
6a5e6884 384
10ba535a
JA
385 return buflen;
386}
387
15dc1934
JA
388static unsigned int get_next_buflen(struct thread_data *td, struct io_u *io_u)
389{
7eb36574
JA
390 struct prof_io_ops *ops = &td->prof_io_ops;
391
392 if (ops->fill_io_u_size)
393 return ops->fill_io_u_size(td, io_u);
15dc1934
JA
394
395 return __get_next_buflen(td, io_u);
396}
397
afe24a5a
JA
398static void set_rwmix_bytes(struct thread_data *td)
399{
afe24a5a
JA
400 unsigned int diff;
401
402 /*
403 * we do time or byte based switch. this is needed because
404 * buffered writes may issue a lot quicker than they complete,
405 * whereas reads do not.
406 */
e47f799f 407 diff = td->o.rwmix[td->rwmix_ddir ^ 1];
04c540d9 408 td->rwmix_issues = (td->io_issues[td->rwmix_ddir] * diff) / 100;
e47f799f
JA
409}
410
411static inline enum fio_ddir get_rand_ddir(struct thread_data *td)
412{
413 unsigned int v;
414 long r;
415
416 r = os_random_long(&td->rwmix_state);
dc873b6f 417 v = 1 + (int) (100.0 * (r / (OS_RAND_MAX + 1.0)));
04c540d9 418 if (v <= td->o.rwmix[DDIR_READ])
e47f799f
JA
419 return DDIR_READ;
420
421 return DDIR_WRITE;
afe24a5a
JA
422}
423
581e7141
JA
424static enum fio_ddir rate_ddir(struct thread_data *td, enum fio_ddir ddir)
425{
426 enum fio_ddir odir = ddir ^ 1;
427 struct timeval t;
428 long usec;
429
ff58fced
JA
430 assert(ddir_rw(ddir));
431
581e7141
JA
432 if (td->rate_pending_usleep[ddir] <= 0)
433 return ddir;
434
435 /*
436 * We have too much pending sleep in this direction. See if we
437 * should switch.
438 */
439 if (td_rw(td)) {
440 /*
441 * Other direction does not have too much pending, switch
442 */
443 if (td->rate_pending_usleep[odir] < 100000)
444 return odir;
445
446 /*
447 * Both directions have pending sleep. Sleep the minimum time
448 * and deduct from both.
449 */
450 if (td->rate_pending_usleep[ddir] <=
451 td->rate_pending_usleep[odir]) {
452 usec = td->rate_pending_usleep[ddir];
453 } else {
454 usec = td->rate_pending_usleep[odir];
455 ddir = odir;
456 }
457 } else
458 usec = td->rate_pending_usleep[ddir];
459
460 fio_gettime(&t, NULL);
461 usec_sleep(td, usec);
462 usec = utime_since_now(&t);
463
464 td->rate_pending_usleep[ddir] -= usec;
465
466 odir = ddir ^ 1;
467 if (td_rw(td) && __should_check_rate(td, odir))
468 td->rate_pending_usleep[odir] -= usec;
0b9d69ec 469
581e7141
JA
470 return ddir;
471}
472
10ba535a
JA
473/*
474 * Return the data direction for the next io_u. If the job is a
475 * mixed read/write workload, check the rwmix cycle and switch if
476 * necessary.
477 */
1e97cce9 478static enum fio_ddir get_rw_ddir(struct thread_data *td)
10ba535a 479{
581e7141
JA
480 enum fio_ddir ddir;
481
5f9099ea
JA
482 /*
483 * see if it's time to fsync
484 */
485 if (td->o.fsync_blocks &&
486 !(td->io_issues[DDIR_WRITE] % td->o.fsync_blocks) &&
487 td->io_issues[DDIR_WRITE] && should_fsync(td))
488 return DDIR_SYNC;
489
490 /*
491 * see if it's time to fdatasync
492 */
493 if (td->o.fdatasync_blocks &&
494 !(td->io_issues[DDIR_WRITE] % td->o.fdatasync_blocks) &&
495 td->io_issues[DDIR_WRITE] && should_fsync(td))
496 return DDIR_DATASYNC;
497
44f29692
JA
498 /*
499 * see if it's time to sync_file_range
500 */
501 if (td->sync_file_range_nr &&
502 !(td->io_issues[DDIR_WRITE] % td->sync_file_range_nr) &&
503 td->io_issues[DDIR_WRITE] && should_fsync(td))
504 return DDIR_SYNC_FILE_RANGE;
505
10ba535a 506 if (td_rw(td)) {
10ba535a
JA
507 /*
508 * Check if it's time to seed a new data direction.
509 */
e4928662 510 if (td->io_issues[td->rwmix_ddir] >= td->rwmix_issues) {
e47f799f
JA
511 /*
512 * Put a top limit on how many bytes we do for
513 * one data direction, to avoid overflowing the
514 * ranges too much
515 */
516 ddir = get_rand_ddir(td);
e47f799f
JA
517
518 if (ddir != td->rwmix_ddir)
519 set_rwmix_bytes(td);
520
521 td->rwmix_ddir = ddir;
10ba535a 522 }
581e7141 523 ddir = td->rwmix_ddir;
10ba535a 524 } else if (td_read(td))
581e7141 525 ddir = DDIR_READ;
10ba535a 526 else
581e7141
JA
527 ddir = DDIR_WRITE;
528
529 td->rwmix_ddir = rate_ddir(td, ddir);
530 return td->rwmix_ddir;
10ba535a
JA
531}
532
1ef2b6be
JA
533static void set_rw_ddir(struct thread_data *td, struct io_u *io_u)
534{
535 io_u->ddir = get_rw_ddir(td);
536
537 if (io_u->ddir == DDIR_WRITE && (td->io_ops->flags & FIO_BARRIER) &&
538 td->o.barrier_blocks &&
539 !(td->io_issues[DDIR_WRITE] % td->o.barrier_blocks) &&
540 td->io_issues[DDIR_WRITE])
541 io_u->flags |= IO_U_F_BARRIER;
542}
543
e8462bd8 544void put_file_log(struct thread_data *td, struct fio_file *f)
60f2c658
JA
545{
546 int ret = put_file(td, f);
547
548 if (ret)
549 td_verror(td, ret, "file close");
550}
551
10ba535a
JA
552void put_io_u(struct thread_data *td, struct io_u *io_u)
553{
e8462bd8
JA
554 td_io_u_lock(td);
555
0c6e7517 556 io_u->flags |= IO_U_F_FREE;
e8462bd8 557 io_u->flags &= ~IO_U_F_FREE_DEF;
0c6e7517 558
60f2c658
JA
559 if (io_u->file)
560 put_file_log(td, io_u->file);
2dbdab7e 561
10ba535a 562 io_u->file = NULL;
0c41214f
RR
563 if (io_u->flags & IO_U_F_IN_CUR_DEPTH)
564 td->cur_depth--;
e8462bd8 565 flist_del_init(&io_u->list);
01743ee1 566 flist_add(&io_u->list, &td->io_u_freelist);
e8462bd8
JA
567 td_io_u_unlock(td);
568 td_io_u_free_notify(td);
10ba535a
JA
569}
570
f2bba182
RR
571void clear_io_u(struct thread_data *td, struct io_u *io_u)
572{
573 io_u->flags &= ~IO_U_F_FLIGHT;
574 put_io_u(td, io_u);
575}
576
755200a3
JA
577void requeue_io_u(struct thread_data *td, struct io_u **io_u)
578{
579 struct io_u *__io_u = *io_u;
580
465221b0
JA
581 dprint(FD_IO, "requeue %p\n", __io_u);
582
e8462bd8
JA
583 td_io_u_lock(td);
584
4d2e0f49 585 __io_u->flags |= IO_U_F_FREE;
ff58fced 586 if ((__io_u->flags & IO_U_F_FLIGHT) && ddir_rw(__io_u->ddir))
e4f54adb 587 td->io_issues[__io_u->ddir]--;
5ec10eaa 588
4d2e0f49 589 __io_u->flags &= ~IO_U_F_FLIGHT;
0c41214f
RR
590 if (__io_u->flags & IO_U_F_IN_CUR_DEPTH)
591 td->cur_depth--;
01743ee1
JA
592 flist_del(&__io_u->list);
593 flist_add_tail(&__io_u->list, &td->io_u_requeues);
e8462bd8 594 td_io_u_unlock(td);
755200a3
JA
595 *io_u = NULL;
596}
597
9bf2061e 598static int fill_io_u(struct thread_data *td, struct io_u *io_u)
10ba535a 599{
b4c5e1ac
JA
600 if (td->io_ops->flags & FIO_NOIO)
601 goto out;
602
1ef2b6be 603 set_rw_ddir(td, io_u);
5f9099ea 604
87dc1ab1 605 /*
ff58fced 606 * fsync() or fdatasync() or trim etc, we are done
87dc1ab1 607 */
ff58fced 608 if (!ddir_rw(io_u->ddir))
c38e9468 609 goto out;
a00735e6 610
48f5abd3
JA
611 /*
612 * See if it's time to switch to a new zone
613 */
614 if (td->zone_bytes >= td->o.zone_size) {
615 td->zone_bytes = 0;
616 io_u->file->last_pos += td->o.zone_skip;
617 td->io_skip_bytes += td->o.zone_skip;
618 }
619
10ba535a 620 /*
c685b5b2
JA
621 * No log, let the seq/rand engine retrieve the next buflen and
622 * position.
10ba535a 623 */
2ba1c290
JA
624 if (get_next_offset(td, io_u)) {
625 dprint(FD_IO, "io_u %p, failed getting offset\n", io_u);
bca4ed4d 626 return 1;
2ba1c290 627 }
10ba535a 628
9bf2061e 629 io_u->buflen = get_next_buflen(td, io_u);
2ba1c290
JA
630 if (!io_u->buflen) {
631 dprint(FD_IO, "io_u %p, failed getting buflen\n", io_u);
bca4ed4d 632 return 1;
2ba1c290 633 }
bca4ed4d 634
2ba1c290
JA
635 if (io_u->offset + io_u->buflen > io_u->file->real_file_size) {
636 dprint(FD_IO, "io_u %p, offset too large\n", io_u);
4ba66134
JA
637 dprint(FD_IO, " off=%llu/%lu > %llu\n", io_u->offset,
638 io_u->buflen, io_u->file->real_file_size);
6a5e6884 639 return 1;
2ba1c290 640 }
6a5e6884 641
bca4ed4d
JA
642 /*
643 * mark entry before potentially trimming io_u
644 */
303032ae 645 if (td_random(td) && file_randommap(td, io_u->file))
9bf2061e 646 mark_random_map(td, io_u);
bca4ed4d
JA
647
648 /*
649 * If using a write iolog, store this entry.
650 */
c38e9468 651out:
2ba1c290 652 dprint_io_u(io_u, "fill_io_u");
d9d91e39 653 td->zone_bytes += io_u->buflen;
f29b25a3 654 log_io_u(td, io_u);
bca4ed4d 655 return 0;
10ba535a
JA
656}
657
838bc709
JA
658static void __io_u_mark_map(unsigned int *map, unsigned int nr)
659{
2b13e716 660 int idx = 0;
838bc709
JA
661
662 switch (nr) {
663 default:
2b13e716 664 idx = 6;
838bc709
JA
665 break;
666 case 33 ... 64:
2b13e716 667 idx = 5;
838bc709
JA
668 break;
669 case 17 ... 32:
2b13e716 670 idx = 4;
838bc709
JA
671 break;
672 case 9 ... 16:
2b13e716 673 idx = 3;
838bc709
JA
674 break;
675 case 5 ... 8:
2b13e716 676 idx = 2;
838bc709
JA
677 break;
678 case 1 ... 4:
2b13e716 679 idx = 1;
838bc709
JA
680 case 0:
681 break;
682 }
683
2b13e716 684 map[idx]++;
838bc709
JA
685}
686
687void io_u_mark_submit(struct thread_data *td, unsigned int nr)
688{
689 __io_u_mark_map(td->ts.io_u_submit, nr);
690 td->ts.total_submit++;
691}
692
693void io_u_mark_complete(struct thread_data *td, unsigned int nr)
694{
695 __io_u_mark_map(td->ts.io_u_complete, nr);
696 td->ts.total_complete++;
697}
698
d8005759 699void io_u_mark_depth(struct thread_data *td, unsigned int nr)
71619dc2 700{
2b13e716 701 int idx = 0;
71619dc2
JA
702
703 switch (td->cur_depth) {
704 default:
2b13e716 705 idx = 6;
a783e61a 706 break;
71619dc2 707 case 32 ... 63:
2b13e716 708 idx = 5;
a783e61a 709 break;
71619dc2 710 case 16 ... 31:
2b13e716 711 idx = 4;
a783e61a 712 break;
71619dc2 713 case 8 ... 15:
2b13e716 714 idx = 3;
a783e61a 715 break;
71619dc2 716 case 4 ... 7:
2b13e716 717 idx = 2;
a783e61a 718 break;
71619dc2 719 case 2 ... 3:
2b13e716 720 idx = 1;
71619dc2
JA
721 case 1:
722 break;
723 }
724
2b13e716 725 td->ts.io_u_map[idx] += nr;
71619dc2
JA
726}
727
04a0feae
JA
728static void io_u_mark_lat_usec(struct thread_data *td, unsigned long usec)
729{
2b13e716 730 int idx = 0;
04a0feae
JA
731
732 assert(usec < 1000);
733
734 switch (usec) {
735 case 750 ... 999:
2b13e716 736 idx = 9;
04a0feae
JA
737 break;
738 case 500 ... 749:
2b13e716 739 idx = 8;
04a0feae
JA
740 break;
741 case 250 ... 499:
2b13e716 742 idx = 7;
04a0feae
JA
743 break;
744 case 100 ... 249:
2b13e716 745 idx = 6;
04a0feae
JA
746 break;
747 case 50 ... 99:
2b13e716 748 idx = 5;
04a0feae
JA
749 break;
750 case 20 ... 49:
2b13e716 751 idx = 4;
04a0feae
JA
752 break;
753 case 10 ... 19:
2b13e716 754 idx = 3;
04a0feae
JA
755 break;
756 case 4 ... 9:
2b13e716 757 idx = 2;
04a0feae
JA
758 break;
759 case 2 ... 3:
2b13e716 760 idx = 1;
04a0feae
JA
761 case 0 ... 1:
762 break;
763 }
764
2b13e716
JA
765 assert(idx < FIO_IO_U_LAT_U_NR);
766 td->ts.io_u_lat_u[idx]++;
04a0feae
JA
767}
768
769static void io_u_mark_lat_msec(struct thread_data *td, unsigned long msec)
ec118304 770{
2b13e716 771 int idx = 0;
ec118304
JA
772
773 switch (msec) {
774 default:
2b13e716 775 idx = 11;
04a0feae 776 break;
8abdce66 777 case 1000 ... 1999:
2b13e716 778 idx = 10;
04a0feae 779 break;
8abdce66 780 case 750 ... 999:
2b13e716 781 idx = 9;
04a0feae 782 break;
8abdce66 783 case 500 ... 749:
2b13e716 784 idx = 8;
04a0feae 785 break;
8abdce66 786 case 250 ... 499:
2b13e716 787 idx = 7;
04a0feae 788 break;
8abdce66 789 case 100 ... 249:
2b13e716 790 idx = 6;
04a0feae 791 break;
8abdce66 792 case 50 ... 99:
2b13e716 793 idx = 5;
04a0feae 794 break;
8abdce66 795 case 20 ... 49:
2b13e716 796 idx = 4;
04a0feae 797 break;
8abdce66 798 case 10 ... 19:
2b13e716 799 idx = 3;
04a0feae 800 break;
8abdce66 801 case 4 ... 9:
2b13e716 802 idx = 2;
04a0feae 803 break;
ec118304 804 case 2 ... 3:
2b13e716 805 idx = 1;
ec118304
JA
806 case 0 ... 1:
807 break;
808 }
809
2b13e716
JA
810 assert(idx < FIO_IO_U_LAT_M_NR);
811 td->ts.io_u_lat_m[idx]++;
04a0feae
JA
812}
813
814static void io_u_mark_latency(struct thread_data *td, unsigned long usec)
815{
816 if (usec < 1000)
817 io_u_mark_lat_usec(td, usec);
818 else
819 io_u_mark_lat_msec(td, usec / 1000);
ec118304
JA
820}
821
0aabe160
JA
822/*
823 * Get next file to service by choosing one at random
824 */
2cc52930
JA
825static struct fio_file *get_next_file_rand(struct thread_data *td,
826 enum fio_file_flags goodf,
d6aed795 827 enum fio_file_flags badf)
0aabe160 828{
0aabe160 829 struct fio_file *f;
1c178180 830 int fno;
0aabe160
JA
831
832 do {
7c83c089 833 long r = os_random_long(&td->next_file_state);
87b10676 834 int opened = 0;
7c83c089 835
5ec10eaa 836 fno = (unsigned int) ((double) td->o.nr_files
dc873b6f 837 * (r / (OS_RAND_MAX + 1.0)));
126d65c6 838 f = td->files[fno];
d6aed795 839 if (fio_file_done(f))
059e63c0 840 continue;
1c178180 841
d6aed795 842 if (!fio_file_open(f)) {
87b10676
JA
843 int err;
844
845 err = td_io_open_file(td, f);
846 if (err)
847 continue;
848 opened = 1;
849 }
850
2ba1c290
JA
851 if ((!goodf || (f->flags & goodf)) && !(f->flags & badf)) {
852 dprint(FD_FILE, "get_next_file_rand: %p\n", f);
0aabe160 853 return f;
2ba1c290 854 }
87b10676
JA
855 if (opened)
856 td_io_close_file(td, f);
0aabe160
JA
857 } while (1);
858}
859
860/*
861 * Get next file to service by doing round robin between all available ones
862 */
1c178180
JA
863static struct fio_file *get_next_file_rr(struct thread_data *td, int goodf,
864 int badf)
3d7c391d
JA
865{
866 unsigned int old_next_file = td->next_file;
867 struct fio_file *f;
868
869 do {
87b10676
JA
870 int opened = 0;
871
126d65c6 872 f = td->files[td->next_file];
3d7c391d
JA
873
874 td->next_file++;
2dc1bbeb 875 if (td->next_file >= td->o.nr_files)
3d7c391d
JA
876 td->next_file = 0;
877
87b10676 878 dprint(FD_FILE, "trying file %s %x\n", f->file_name, f->flags);
d6aed795 879 if (fio_file_done(f)) {
d5ed68ea 880 f = NULL;
059e63c0 881 continue;
d5ed68ea 882 }
059e63c0 883
d6aed795 884 if (!fio_file_open(f)) {
87b10676
JA
885 int err;
886
887 err = td_io_open_file(td, f);
b5696bfc
JA
888 if (err) {
889 dprint(FD_FILE, "error %d on open of %s\n",
890 err, f->file_name);
87c27b45 891 f = NULL;
87b10676 892 continue;
b5696bfc 893 }
87b10676
JA
894 opened = 1;
895 }
896
0b9d69ec
JA
897 dprint(FD_FILE, "goodf=%x, badf=%x, ff=%x\n", goodf, badf,
898 f->flags);
1c178180 899 if ((!goodf || (f->flags & goodf)) && !(f->flags & badf))
3d7c391d
JA
900 break;
901
87b10676
JA
902 if (opened)
903 td_io_close_file(td, f);
904
3d7c391d
JA
905 f = NULL;
906 } while (td->next_file != old_next_file);
907
2ba1c290 908 dprint(FD_FILE, "get_next_file_rr: %p\n", f);
3d7c391d
JA
909 return f;
910}
911
7eb36574 912static struct fio_file *__get_next_file(struct thread_data *td)
bdb4e2e9 913{
1907dbc6
JA
914 struct fio_file *f;
915
2dc1bbeb 916 assert(td->o.nr_files <= td->files_index);
1c178180 917
b5696bfc 918 if (td->nr_done_files >= td->o.nr_files) {
5ec10eaa
JA
919 dprint(FD_FILE, "get_next_file: nr_open=%d, nr_done=%d,"
920 " nr_files=%d\n", td->nr_open_files,
921 td->nr_done_files,
922 td->o.nr_files);
bdb4e2e9 923 return NULL;
2ba1c290 924 }
bdb4e2e9 925
1907dbc6 926 f = td->file_service_file;
d6aed795 927 if (f && fio_file_open(f) && !fio_file_closing(f)) {
a086c257
JA
928 if (td->o.file_service_type == FIO_FSERVICE_SEQ)
929 goto out;
930 if (td->file_service_left--)
931 goto out;
932 }
1907dbc6 933
a086c257
JA
934 if (td->o.file_service_type == FIO_FSERVICE_RR ||
935 td->o.file_service_type == FIO_FSERVICE_SEQ)
d6aed795 936 f = get_next_file_rr(td, FIO_FILE_open, FIO_FILE_closing);
bdb4e2e9 937 else
d6aed795 938 f = get_next_file_rand(td, FIO_FILE_open, FIO_FILE_closing);
1907dbc6
JA
939
940 td->file_service_file = f;
941 td->file_service_left = td->file_service_nr - 1;
2ba1c290 942out:
683023e8 943 dprint(FD_FILE, "get_next_file: %p [%s]\n", f, f->file_name);
1907dbc6 944 return f;
bdb4e2e9
JA
945}
946
7eb36574
JA
947static struct fio_file *get_next_file(struct thread_data *td)
948{
949 struct prof_io_ops *ops = &td->prof_io_ops;
950
951 if (ops->get_next_file)
952 return ops->get_next_file(td);
953
954 return __get_next_file(td);
955}
956
429f6675
JA
957static int set_io_u_file(struct thread_data *td, struct io_u *io_u)
958{
959 struct fio_file *f;
960
961 do {
962 f = get_next_file(td);
963 if (!f)
964 return 1;
965
429f6675
JA
966 io_u->file = f;
967 get_file(f);
968
969 if (!fill_io_u(td, io_u))
970 break;
971
b5696bfc 972 put_file_log(td, f);
429f6675 973 td_io_close_file(td, f);
b5696bfc 974 io_u->file = NULL;
d6aed795 975 fio_file_set_done(f);
429f6675 976 td->nr_done_files++;
0b9d69ec
JA
977 dprint(FD_FILE, "%s: is done (%d of %d)\n", f->file_name,
978 td->nr_done_files, td->o.nr_files);
429f6675
JA
979 } while (1);
980
981 return 0;
982}
983
984
10ba535a
JA
985struct io_u *__get_io_u(struct thread_data *td)
986{
987 struct io_u *io_u = NULL;
988
e8462bd8
JA
989 td_io_u_lock(td);
990
991again:
01743ee1
JA
992 if (!flist_empty(&td->io_u_requeues))
993 io_u = flist_entry(td->io_u_requeues.next, struct io_u, list);
755200a3 994 else if (!queue_full(td)) {
01743ee1 995 io_u = flist_entry(td->io_u_freelist.next, struct io_u, list);
10ba535a 996
6040dabc 997 io_u->buflen = 0;
10ba535a 998 io_u->resid = 0;
755200a3 999 io_u->file = NULL;
d7762cf8 1000 io_u->end_io = NULL;
755200a3
JA
1001 }
1002
1003 if (io_u) {
0c6e7517 1004 assert(io_u->flags & IO_U_F_FREE);
2ecc1b57 1005 io_u->flags &= ~(IO_U_F_FREE | IO_U_F_FREE_DEF);
1ef2b6be 1006 io_u->flags &= ~(IO_U_F_TRIMMED | IO_U_F_BARRIER);
0c6e7517 1007
755200a3 1008 io_u->error = 0;
01743ee1
JA
1009 flist_del(&io_u->list);
1010 flist_add(&io_u->list, &td->io_u_busylist);
10ba535a 1011 td->cur_depth++;
0c41214f 1012 io_u->flags |= IO_U_F_IN_CUR_DEPTH;
1dec3e07
JA
1013 } else if (td->o.verify_async) {
1014 /*
1015 * We ran out, wait for async verify threads to finish and
1016 * return one
1017 */
1018 pthread_cond_wait(&td->free_cond, &td->io_u_lock);
1019 goto again;
10ba535a
JA
1020 }
1021
e8462bd8 1022 td_io_u_unlock(td);
10ba535a
JA
1023 return io_u;
1024}
1025
0d29de83 1026static int check_get_trim(struct thread_data *td, struct io_u *io_u)
10ba535a 1027{
0d29de83
JA
1028 if (td->o.trim_backlog && td->trim_entries) {
1029 int get_trim = 0;
10ba535a 1030
0d29de83
JA
1031 if (td->trim_batch) {
1032 td->trim_batch--;
1033 get_trim = 1;
1034 } else if (!(td->io_hist_len % td->o.trim_backlog) &&
1035 td->last_ddir != DDIR_READ) {
1036 td->trim_batch = td->o.trim_batch;
1037 if (!td->trim_batch)
1038 td->trim_batch = td->o.trim_backlog;
1039 get_trim = 1;
1040 }
1041
1042 if (get_trim && !get_next_trim(td, io_u))
1043 return 1;
2ba1c290 1044 }
10ba535a 1045
0d29de83
JA
1046 return 0;
1047}
1048
1049static int check_get_verify(struct thread_data *td, struct io_u *io_u)
1050{
9e144189
JA
1051 if (td->o.verify_backlog && td->io_hist_len) {
1052 int get_verify = 0;
1053
1054 if (td->verify_batch) {
1055 td->verify_batch--;
1056 get_verify = 1;
1057 } else if (!(td->io_hist_len % td->o.verify_backlog) &&
1058 td->last_ddir != DDIR_READ) {
1059 td->verify_batch = td->o.verify_batch;
f8a75c99
JA
1060 if (!td->verify_batch)
1061 td->verify_batch = td->o.verify_backlog;
9e144189
JA
1062 get_verify = 1;
1063 }
1064
1065 if (get_verify && !get_next_verify(td, io_u))
0d29de83 1066 return 1;
9e144189
JA
1067 }
1068
0d29de83
JA
1069 return 0;
1070}
1071
1072/*
1073 * Return an io_u to be processed. Gets a buflen and offset, sets direction,
1074 * etc. The returned io_u is fully ready to be prepped and submitted.
1075 */
1076struct io_u *get_io_u(struct thread_data *td)
1077{
1078 struct fio_file *f;
1079 struct io_u *io_u;
1080
1081 io_u = __get_io_u(td);
1082 if (!io_u) {
1083 dprint(FD_IO, "__get_io_u failed\n");
1084 return NULL;
1085 }
1086
1087 if (check_get_verify(td, io_u))
1088 goto out;
1089 if (check_get_trim(td, io_u))
1090 goto out;
1091
755200a3
JA
1092 /*
1093 * from a requeue, io_u already setup
1094 */
1095 if (io_u->file)
77f392bf 1096 goto out;
755200a3 1097
429f6675
JA
1098 /*
1099 * If using an iolog, grab next piece if any available.
1100 */
1101 if (td->o.read_iolog_file) {
1102 if (read_iolog_get(td, io_u))
1103 goto err_put;
2ba1c290
JA
1104 } else if (set_io_u_file(td, io_u)) {
1105 dprint(FD_IO, "io_u %p, setting file failed\n", io_u);
429f6675 1106 goto err_put;
2ba1c290 1107 }
5ec10eaa 1108
429f6675 1109 f = io_u->file;
d6aed795 1110 assert(fio_file_open(f));
97af62ce 1111
ff58fced 1112 if (ddir_rw(io_u->ddir)) {
d0656a93 1113 if (!io_u->buflen && !(td->io_ops->flags & FIO_NOIO)) {
2ba1c290 1114 dprint(FD_IO, "get_io_u: zero buflen on %p\n", io_u);
429f6675 1115 goto err_put;
2ba1c290 1116 }
10ba535a 1117
38dad62d 1118 f->last_start = io_u->offset;
36167d82 1119 f->last_pos = io_u->offset + io_u->buflen;
10ba535a 1120
c311cd2a 1121 if (td->o.verify != VERIFY_NONE && io_u->ddir == DDIR_WRITE)
87dc1ab1 1122 populate_verify_io_u(td, io_u);
e4dad9c6
JA
1123 else if (td->o.refill_buffers && io_u->ddir == DDIR_WRITE)
1124 io_u_fill_buffer(td, io_u, io_u->xfer_buflen);
cbe8d756
RR
1125 else if (io_u->ddir == DDIR_READ) {
1126 /*
1127 * Reset the buf_filled parameters so next time if the
1128 * buffer is used for writes it is refilled.
1129 */
cbe8d756
RR
1130 io_u->buf_filled_len = 0;
1131 }
87dc1ab1 1132 }
10ba535a 1133
165faf16
JA
1134 /*
1135 * Set io data pointers.
1136 */
cec6b55d
JA
1137 io_u->xfer_buf = io_u->buf;
1138 io_u->xfer_buflen = io_u->buflen;
5973cafb 1139
6ac7a331 1140out:
0d29de83 1141 assert(io_u->file);
429f6675 1142 if (!td_io_prep(td, io_u)) {
993bf48b
JA
1143 if (!td->o.disable_slat)
1144 fio_gettime(&io_u->start_time, NULL);
429f6675 1145 return io_u;
36167d82 1146 }
429f6675 1147err_put:
2ba1c290 1148 dprint(FD_IO, "get_io_u failed\n");
429f6675
JA
1149 put_io_u(td, io_u);
1150 return NULL;
10ba535a
JA
1151}
1152
5451792e
JA
1153void io_u_log_error(struct thread_data *td, struct io_u *io_u)
1154{
825f818e
JA
1155 const char *msg[] = { "read", "write", "sync", "datasync",
1156 "sync_file_range", "wait", "trim" };
1157
1158
5451792e
JA
1159
1160 log_err("fio: io_u error");
1161
1162 if (io_u->file)
1163 log_err(" on file %s", io_u->file->file_name);
1164
1165 log_err(": %s\n", strerror(io_u->error));
1166
5ec10eaa
JA
1167 log_err(" %s offset=%llu, buflen=%lu\n", msg[io_u->ddir],
1168 io_u->offset, io_u->xfer_buflen);
5451792e
JA
1169
1170 if (!td->error)
1171 td_verror(td, io_u->error, "io_u error");
1172}
1173
97601024
JA
1174static void io_completed(struct thread_data *td, struct io_u *io_u,
1175 struct io_completion_data *icd)
10ba535a 1176{
dbad30b0
JA
1177 /*
1178 * Older gcc's are too dumb to realize that usec is always used
1179 * initialized, silence that warning.
1180 */
1181 unsigned long uninitialized_var(usec);
44f29692 1182 struct fio_file *f;
10ba535a 1183
2ba1c290
JA
1184 dprint_io_u(io_u, "io complete");
1185
2ecc1b57 1186 td_io_u_lock(td);
0c6e7517 1187 assert(io_u->flags & IO_U_F_FLIGHT);
38dad62d 1188 io_u->flags &= ~(IO_U_F_FLIGHT | IO_U_F_BUSY_OK);
2ecc1b57 1189 td_io_u_unlock(td);
0c6e7517 1190
5f9099ea 1191 if (ddir_sync(io_u->ddir)) {
87dc1ab1 1192 td->last_was_sync = 1;
44f29692
JA
1193 f = io_u->file;
1194 if (f) {
1195 f->first_write = -1ULL;
1196 f->last_write = -1ULL;
1197 }
87dc1ab1
JA
1198 return;
1199 }
1200
1201 td->last_was_sync = 0;
9e144189 1202 td->last_ddir = io_u->ddir;
87dc1ab1 1203
ff58fced 1204 if (!io_u->error && ddir_rw(io_u->ddir)) {
10ba535a 1205 unsigned int bytes = io_u->buflen - io_u->resid;
1e97cce9 1206 const enum fio_ddir idx = io_u->ddir;
ba3e4e0c 1207 const enum fio_ddir odx = io_u->ddir ^ 1;
b29ee5b3 1208 int ret;
10ba535a 1209
b29ee5b3
JA
1210 td->io_blocks[idx]++;
1211 td->io_bytes[idx] += bytes;
1212 td->this_io_bytes[idx] += bytes;
10ba535a 1213
44f29692
JA
1214 if (idx == DDIR_WRITE) {
1215 f = io_u->file;
1216 if (f) {
1217 if (f->first_write == -1ULL ||
1218 io_u->offset < f->first_write)
1219 f->first_write = io_u->offset;
1220 if (f->last_write == -1ULL ||
1221 ((io_u->offset + bytes) > f->last_write))
1222 f->last_write = io_u->offset + bytes;
1223 }
1224 }
1225
b29ee5b3 1226 if (ramp_time_over(td)) {
40e1a6f0 1227 unsigned long uninitialized_var(lusec);
40e1a6f0
JA
1228
1229 if (!td->o.disable_clat || !td->o.disable_bw)
1230 lusec = utime_since(&io_u->issue_time,
1231 &icd->time);
02af0988
JA
1232 if (!td->o.disable_lat) {
1233 unsigned long tusec;
721938ae 1234
02af0988
JA
1235 tusec = utime_since(&io_u->start_time,
1236 &icd->time);
1237 add_lat_sample(td, idx, tusec, bytes);
1238 }
9520ebb9 1239 if (!td->o.disable_clat) {
01a1caa5 1240 add_clat_sample(td, idx, lusec, bytes);
40e1a6f0 1241 io_u_mark_latency(td, lusec);
9520ebb9
JA
1242 }
1243 if (!td->o.disable_bw)
306ddc97 1244 add_bw_sample(td, idx, bytes, &icd->time);
b23b6a2f 1245 if (__should_check_rate(td, idx)) {
ba3e4e0c
RR
1246 td->rate_pending_usleep[idx] =
1247 ((td->this_io_bytes[idx] *
1248 td->rate_nsec_cycle[idx]) / 1000 -
1249 utime_since_now(&td->start));
b23b6a2f 1250 }
581e7141 1251 if (__should_check_rate(td, idx ^ 1))
ba3e4e0c
RR
1252 td->rate_pending_usleep[odx] =
1253 ((td->this_io_bytes[odx] *
1254 td->rate_nsec_cycle[odx]) / 1000 -
1255 utime_since_now(&td->start));
721938ae 1256 }
10ba535a 1257
660a1cb5 1258 if (td_write(td) && idx == DDIR_WRITE &&
8670579e 1259 td->o.do_verify &&
41128405 1260 td->o.verify != VERIFY_NONE)
10ba535a
JA
1261 log_io_piece(td, io_u);
1262
b29ee5b3 1263 icd->bytes_done[idx] += bytes;
3af6ef39 1264
d7762cf8 1265 if (io_u->end_io) {
36690c9b 1266 ret = io_u->end_io(td, io_u);
3af6ef39
JA
1267 if (ret && !icd->error)
1268 icd->error = ret;
1269 }
ff58fced 1270 } else if (io_u->error) {
10ba535a 1271 icd->error = io_u->error;
5451792e
JA
1272 io_u_log_error(td, io_u);
1273 }
f2bba182
RR
1274 if (td->o.continue_on_error && icd->error &&
1275 td_non_fatal_error(icd->error)) {
1276 /*
1277 * If there is a non_fatal error, then add to the error count
1278 * and clear all the errors.
1279 */
1280 update_error_count(td, icd->error);
1281 td_clear_error(td);
1282 icd->error = 0;
1283 io_u->error = 0;
1284 }
10ba535a
JA
1285}
1286
9520ebb9
JA
1287static void init_icd(struct thread_data *td, struct io_completion_data *icd,
1288 int nr)
10ba535a 1289{
9520ebb9
JA
1290 if (!td->o.disable_clat || !td->o.disable_bw)
1291 fio_gettime(&icd->time, NULL);
02bcaa8c 1292
3af6ef39
JA
1293 icd->nr = nr;
1294
10ba535a
JA
1295 icd->error = 0;
1296 icd->bytes_done[0] = icd->bytes_done[1] = 0;
36167d82
JA
1297}
1298
97601024
JA
1299static void ios_completed(struct thread_data *td,
1300 struct io_completion_data *icd)
36167d82
JA
1301{
1302 struct io_u *io_u;
1303 int i;
1304
10ba535a
JA
1305 for (i = 0; i < icd->nr; i++) {
1306 io_u = td->io_ops->event(td, i);
1307
1308 io_completed(td, io_u, icd);
e8462bd8
JA
1309
1310 if (!(io_u->flags & IO_U_F_FREE_DEF))
1311 put_io_u(td, io_u);
10ba535a
JA
1312 }
1313}
97601024 1314
e7e6cfb4
JA
1315/*
1316 * Complete a single io_u for the sync engines.
1317 */
581e7141
JA
1318int io_u_sync_complete(struct thread_data *td, struct io_u *io_u,
1319 unsigned long *bytes)
97601024
JA
1320{
1321 struct io_completion_data icd;
1322
9520ebb9 1323 init_icd(td, &icd, 1);
97601024 1324 io_completed(td, io_u, &icd);
e8462bd8
JA
1325
1326 if (!(io_u->flags & IO_U_F_FREE_DEF))
1327 put_io_u(td, io_u);
97601024 1328
581e7141
JA
1329 if (icd.error) {
1330 td_verror(td, icd.error, "io_u_sync_complete");
1331 return -1;
1332 }
97601024 1333
581e7141
JA
1334 if (bytes) {
1335 bytes[0] += icd.bytes_done[0];
1336 bytes[1] += icd.bytes_done[1];
1337 }
1338
1339 return 0;
97601024
JA
1340}
1341
e7e6cfb4
JA
1342/*
1343 * Called to complete min_events number of io for the async engines.
1344 */
581e7141
JA
1345int io_u_queued_complete(struct thread_data *td, int min_evts,
1346 unsigned long *bytes)
97601024 1347{
97601024 1348 struct io_completion_data icd;
00de55ef 1349 struct timespec *tvp = NULL;
97601024 1350 int ret;
4d06a338 1351 struct timespec ts = { .tv_sec = 0, .tv_nsec = 0, };
97601024 1352
4950421a 1353 dprint(FD_IO, "io_u_queued_completed: min=%d\n", min_evts);
b271fe62 1354
4950421a 1355 if (!min_evts)
00de55ef 1356 tvp = &ts;
97601024 1357
4950421a 1358 ret = td_io_getevents(td, min_evts, td->o.iodepth_batch_complete, tvp);
97601024 1359 if (ret < 0) {
e1161c32 1360 td_verror(td, -ret, "td_io_getevents");
97601024
JA
1361 return ret;
1362 } else if (!ret)
1363 return ret;
1364
9520ebb9 1365 init_icd(td, &icd, ret);
97601024 1366 ios_completed(td, &icd);
581e7141
JA
1367 if (icd.error) {
1368 td_verror(td, icd.error, "io_u_queued_complete");
1369 return -1;
1370 }
97601024 1371
581e7141
JA
1372 if (bytes) {
1373 bytes[0] += icd.bytes_done[0];
1374 bytes[1] += icd.bytes_done[1];
1375 }
1376
1377 return 0;
97601024 1378}
7e77dd02
JA
1379
1380/*
1381 * Call when io_u is really queued, to update the submission latency.
1382 */
1383void io_u_queued(struct thread_data *td, struct io_u *io_u)
1384{
9520ebb9
JA
1385 if (!td->o.disable_slat) {
1386 unsigned long slat_time;
7e77dd02 1387
9520ebb9 1388 slat_time = utime_since(&io_u->start_time, &io_u->issue_time);
29a90ddb 1389 add_slat_sample(td, io_u->ddir, slat_time, io_u->xfer_buflen);
9520ebb9 1390 }
7e77dd02 1391}
433afcb4 1392
5973cafb
JA
1393/*
1394 * "randomly" fill the buffer contents
1395 */
1396void io_u_fill_buffer(struct thread_data *td, struct io_u *io_u,
1397 unsigned int max_bs)
1398{
e84b371e
JA
1399 io_u->buf_filled_len = 0;
1400
637ef8d9
JA
1401 if (!td->o.zero_buffers)
1402 fill_random_buf(io_u->buf, max_bs);
1403 else
1404 memset(io_u->buf, 0, max_bs);
5973cafb 1405}