X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=ioengines.c;h=ae55f951d413fbaeaf92dae3c8eb0746167d4c9d;hp=56149381894abfb56e9bd7a47368cc2773278fde;hb=d619275cfad893e37e8c59e5c9e0bc5ca4946b82;hpb=effd6ff0d9f701a64d6bc46509eedfdcfd12f553 diff --git a/ioengines.c b/ioengines.c index 56149381..ae55f951 100644 --- a/ioengines.c +++ b/ioengines.c @@ -22,39 +22,31 @@ static FLIST_HEAD(engine_list); -static int check_engine_ops(struct ioengine_ops *ops) +static bool check_engine_ops(struct ioengine_ops *ops) { if (ops->version != FIO_IOOPS_VERSION) { log_err("bad ioops version %d (want %d)\n", ops->version, FIO_IOOPS_VERSION); - return 1; + return true; } if (!ops->queue) { log_err("%s: no queue handler\n", ops->name); - return 1; + return true; } /* * sync engines only need a ->queue() */ if (ops->flags & FIO_SYNCIO) - return 0; + return false; - if (!ops->event) { - log_err("%s: no event handler\n", ops->name); - return 1; - } - if (!ops->getevents) { - log_err("%s: no getevents handler\n", ops->name); - return 1; - } - if (!ops->queue) { - log_err("%s: no queue handler\n", ops->name); - return 1; + if (!ops->event || !ops->getevents) { + log_err("%s: no event/getevents handler\n", ops->name); + return true; } - return 0; + return false; } void unregister_ioengine(struct ioengine_ops *ops) @@ -127,17 +119,18 @@ static struct ioengine_ops *dlopen_ioengine(struct thread_data *td, return NULL; } - ops->dlhandle = dlhandle; + td->io_ops_dlhandle = dlhandle; return ops; } struct ioengine_ops *load_ioengine(struct thread_data *td, const char *name) { - struct ioengine_ops *ops, *ret; - char engine[16]; + struct ioengine_ops *ops; + char engine[64]; dprint(FD_IO, "load ioengine %s\n", name); + engine[sizeof(engine) - 1] = '\0'; strncpy(engine, name, sizeof(engine) - 1); /* @@ -161,11 +154,7 @@ struct ioengine_ops *load_ioengine(struct thread_data *td, const char *name) if (check_engine_ops(ops)) return NULL; - ret = malloc(sizeof(*ret)); - memcpy(ret, ops, sizeof(*ret)); - ret->data = NULL; - - return ret; + return ops; } /* @@ -181,10 +170,9 @@ void free_ioengine(struct thread_data *td) td->eo = NULL; } - if (td->io_ops->dlhandle) - dlclose(td->io_ops->dlhandle); + if (td->io_ops_dlhandle) + dlclose(td->io_ops_dlhandle); - free(td->io_ops); td->io_ops = NULL; } @@ -194,7 +182,7 @@ void close_ioengine(struct thread_data *td) if (td->io_ops->cleanup) { td->io_ops->cleanup(td); - td->io_ops->data = NULL; + td->io_ops_data = NULL; } free_ioengine(td); @@ -220,7 +208,7 @@ int td_io_prep(struct thread_data *td, struct io_u *io_u) } int td_io_getevents(struct thread_data *td, unsigned int min, unsigned int max, - struct timespec *t) + const struct timespec *t) { int r = 0; @@ -264,13 +252,15 @@ out: int td_io_queue(struct thread_data *td, struct io_u *io_u) { + const enum fio_ddir ddir = acct_ddir(io_u); + unsigned long buflen = io_u->xfer_buflen; int ret; dprint_io_u(io_u, "queue"); fio_ro_check(td, io_u); assert((io_u->flags & IO_U_F_FLIGHT) == 0); - io_u->flags |= IO_U_F_FLIGHT; + io_u_set(td, io_u, IO_U_F_FLIGHT); assert(fio_file_open(io_u->file)); @@ -282,7 +272,7 @@ int td_io_queue(struct thread_data *td, struct io_u *io_u) io_u->error = 0; io_u->resid = 0; - if (td->io_ops->flags & FIO_SYNCIO) { + if (td_ioengine_flagged(td, FIO_SYNCIO)) { if (fio_fill_issue_time(td)) fio_gettime(&io_u->issue_time, NULL); @@ -294,13 +284,22 @@ int td_io_queue(struct thread_data *td, struct io_u *io_u) sizeof(struct timeval)); } - if (ddir_rw(acct_ddir(io_u))) - td->io_issues[acct_ddir(io_u)]++; + if (ddir_rw(ddir)) { + td->io_issues[ddir]++; + td->io_issue_bytes[ddir] += buflen; + td->rate_io_issue_bytes[ddir] += buflen; + } ret = td->io_ops->queue(td, io_u); unlock_file(td, io_u->file); + if (ret == FIO_Q_BUSY && ddir_rw(ddir)) { + td->io_issues[ddir]--; + td->io_issue_bytes[ddir] -= buflen; + td->rate_io_issue_bytes[ddir] -= buflen; + } + /* * If an error was seen and the io engine didn't propagate it * back to 'td', do so. @@ -318,10 +317,11 @@ int td_io_queue(struct thread_data *td, struct io_u *io_u) td->o.odirect) { log_info("fio: first direct IO errored. File system may not " - "support direct IO, or iomem_align= is bad.\n"); + "support direct IO, or iomem_align= is bad. Try " + "setting direct=0.\n"); } - if (!td->io_ops->commit || ddir_trim(io_u->ddir)) { + if (!td->io_ops->commit || io_u->ddir == DDIR_TRIM) { io_u_mark_submit(td, 1); io_u_mark_complete(td, 1); } @@ -334,10 +334,10 @@ int td_io_queue(struct thread_data *td, struct io_u *io_u) } else if (ret == FIO_Q_QUEUED) { int r; - if (ddir_rw(io_u->ddir)) { - td->io_u_queued++; + td->io_u_queued++; + + if (ddir_rw(io_u->ddir)) td->ts.total_io_u[io_u->ddir]++; - } if (td->io_u_queued >= td->o.iodepth_batch) { r = td_io_commit(td); @@ -346,7 +346,7 @@ int td_io_queue(struct thread_data *td, struct io_u *io_u) } } - if ((td->io_ops->flags & FIO_SYNCIO) == 0) { + if (!td_ioengine_flagged(td, FIO_SYNCIO)) { if (fio_fill_issue_time(td)) fio_gettime(&io_u->issue_time, NULL); @@ -375,7 +375,7 @@ int td_io_init(struct thread_data *td) td->error = ret; } - if (!ret && (td->io_ops->flags & FIO_NOIO)) + if (!ret && td_ioengine_flagged(td, FIO_NOIO)) td->flags |= TD_F_NOIO; return ret; @@ -441,7 +441,7 @@ int td_io_open_file(struct thread_data *td, struct fio_file *f) } } - if (td->io_ops->flags & FIO_DISKLESSIO) + if (td_ioengine_flagged(td, FIO_DISKLESSIO)) goto done; if (td->o.invalidate_cache && file_invalidate_cache(td, f)) @@ -461,6 +461,17 @@ int td_io_open_file(struct thread_data *td, struct fio_file *f) goto err; } } +#ifdef FIO_HAVE_STREAMID + if (td->o.fadvise_stream && + (f->filetype == FIO_TYPE_BD || f->filetype == FIO_TYPE_FILE)) { + off_t stream = td->o.fadvise_stream; + + if (posix_fadvise(f->fd, stream, f->io_size, POSIX_FADV_STREAMID) < 0) { + td_verror(td, errno, "fadvise streamid"); + goto err; + } + } +#endif #ifdef FIO_OS_DIRECTIO /* @@ -510,8 +521,15 @@ int td_io_unlink_file(struct thread_data *td, struct fio_file *f) { if (td->io_ops->unlink_file) return td->io_ops->unlink_file(td, f); - else - return unlink(f->file_name); + else { + int ret; + + ret = unlink(f->file_name); + if (ret < 0) + return errno; + + return 0; + } } int td_io_get_file_size(struct thread_data *td, struct fio_file *f)