X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=fio.c;h=3c64b7b7cab87a1eb0a40d342bb410244a3b360f;hp=78deaf66a732b6e92434cf0ccef52b66b62d5a71;hb=6bb1c841e213b922f621d8ab50e8641e0ab10923;hpb=97601024a53586d77a368763f08be9ee483fdc9c diff --git a/fio.c b/fio.c index 78deaf66..3c64b7b7 100644 --- a/fio.c +++ b/fio.c @@ -136,27 +136,6 @@ static inline int runtime_exceeded(struct thread_data *td, struct timeval *t) return 0; } -static struct fio_file *get_next_file(struct thread_data *td) -{ - unsigned int old_next_file = td->next_file; - struct fio_file *f; - - do { - f = &td->files[td->next_file]; - - td->next_file++; - if (td->next_file >= td->nr_files) - td->next_file = 0; - - if (f->fd != -1) - break; - - f = NULL; - } while (td->next_file != old_next_file); - - return f; -} - /* * When job exits, we can cancel the in-flight IO if we are using async * io. Attempt to do so. @@ -209,6 +188,7 @@ static int fio_io_sync(struct thread_data *td, struct fio_file *f) return 1; } +requeue: ret = td_io_queue(td, io_u); if (ret < 0) { td_verror(td, io_u->error); @@ -224,6 +204,10 @@ static int fio_io_sync(struct thread_data *td, struct fio_file *f) } io_u_sync_complete(td, io_u, NULL); + } else if (ret == FIO_Q_BUSY) { + if (td_io_commit(td)) + return 1; + goto requeue; } return 0; @@ -279,18 +263,23 @@ requeue: io_u->xfer_buf += bytes; goto requeue; } - if (io_u_sync_complete(td, io_u, verify_io_u)) + ret = io_u_sync_complete(td, io_u, verify_io_u); + if (ret) break; continue; case FIO_Q_QUEUED: break; + case FIO_Q_BUSY: + requeue_io_u(td, &io_u); + ret = td_io_commit(td); + break; default: assert(ret < 0); td_verror(td, -ret); break; } - if (ret < 0) + if (ret < 0 || td->error) break; /* @@ -298,7 +287,7 @@ requeue: * completed io_u's first. */ min_events = 0; - if (queue_full(td)) + if (queue_full(td) || ret == FIO_Q_BUSY) min_events = 1; /* @@ -351,7 +340,6 @@ static void do_io(struct thread_data *td) { struct timeval s; unsigned long usec; - struct fio_file *f; int i, ret = 0; td_set_runstate(td, TD_RUNNING); @@ -365,11 +353,7 @@ static void do_io(struct thread_data *td) if (td->terminate) break; - f = get_next_file(td); - if (!f) - break; - - io_u = get_io_u(td, f); + io_u = get_io_u(td); if (!io_u) break; @@ -397,26 +381,33 @@ requeue: } fio_gettime(&comp_time, NULL); bytes_done = io_u_sync_complete(td, io_u, NULL); + if (bytes_done < 0) + ret = bytes_done; break; case FIO_Q_QUEUED: break; + case FIO_Q_BUSY: + requeue_io_u(td, &io_u); + ret = td_io_commit(td); + break; default: assert(ret < 0); put_io_u(td, io_u); break; } - if (ret < 0) + if (ret < 0 || td->error) break; - add_slat_sample(td, io_u->ddir, mtime_since(&io_u->start_time, &io_u->issue_time)); + if (io_u) + add_slat_sample(td, io_u->ddir, mtime_since(&io_u->start_time, &io_u->issue_time)); /* * See if we need to complete some commands */ - if (ret == FIO_Q_QUEUED) { + if (ret == FIO_Q_QUEUED || ret == FIO_Q_BUSY) { min_evts = 0; - if (queue_full(td)) + if (queue_full(td) || ret == FIO_Q_BUSY) min_evts = 1; fio_gettime(&comp_time, NULL); @@ -462,6 +453,8 @@ requeue: } if (!td->error) { + struct fio_file *f; + if (td->cur_depth) cleanup_pending_aio(td); @@ -630,6 +623,7 @@ static void *thread_main(void *data) INIT_LIST_HEAD(&td->io_u_freelist); INIT_LIST_HEAD(&td->io_u_busylist); + INIT_LIST_HEAD(&td->io_u_requeues); INIT_LIST_HEAD(&td->io_hist_list); INIT_LIST_HEAD(&td->io_log_list);