X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=ioengines.c;h=b9200ba9223488923ed2cc879d58971c31c70dab;hp=1bfc06f96d12bf15f07e8aded629e8fa9c7cc92d;hb=e08e2dd7b77f99e4bb904fc1df2395c2fe2ffbbe;hpb=d25f5ae81c4a5dedf4f5c5a2323a20fe77e5b86f diff --git a/ioengines.c b/ioengines.c index 1bfc06f9..b9200ba9 100644 --- a/ioengines.c +++ b/ioengines.c @@ -9,7 +9,6 @@ * generic io engine that could be used for other projects. * */ -#include #include #include #include @@ -19,6 +18,7 @@ #include "fio.h" #include "diskutil.h" +#include "zbd.h" static FLIST_HEAD(engine_list); @@ -52,14 +52,12 @@ static bool check_engine_ops(struct ioengine_ops *ops) void unregister_ioengine(struct ioengine_ops *ops) { dprint(FD_IO, "ioengine %s unregistered\n", ops->name); - flist_del(&ops->list); - INIT_FLIST_HEAD(&ops->list); + flist_del_init(&ops->list); } void register_ioengine(struct ioengine_ops *ops) { dprint(FD_IO, "ioengine %s registered\n", ops->name); - INIT_FLIST_HEAD(&ops->list); flist_add_tail(&ops->list, &engine_list); } @@ -123,19 +121,15 @@ static struct ioengine_ops *dlopen_ioengine(struct thread_data *td, return ops; } -static struct ioengine_ops *__load_ioengine(const char *name) +static struct ioengine_ops *__load_ioengine(const char *engine) { - char engine[64]; - - engine[sizeof(engine) - 1] = '\0'; - strncpy(engine, name, sizeof(engine) - 1); - /* * linux libaio has alias names, so convert to what we want */ - if (!strncmp(engine, "linuxaio", 8) || !strncmp(engine, "aio", 3)) { - dprint(FD_IO, "converting ioengine name: %s -> libaio\n", name); - strcpy(engine, "libaio"); + if (!strncmp(engine, "linuxaio", 8)) { + dprint(FD_IO, "converting ioengine name: %s -> libaio\n", + engine); + engine = "libaio"; } dprint(FD_IO, "load ioengine %s\n", engine); @@ -196,8 +190,10 @@ void free_ioengine(struct thread_data *td) td->eo = NULL; } - if (td->io_ops_dlhandle) + if (td->io_ops_dlhandle) { dlclose(td->io_ops_dlhandle); + td->io_ops_dlhandle = NULL; + } td->io_ops = NULL; } @@ -224,7 +220,8 @@ int td_io_prep(struct thread_data *td, struct io_u *io_u) if (td->io_ops->prep) { int ret = td->io_ops->prep(td, io_u); - dprint(FD_IO, "->prep(%p)=%d\n", io_u, ret); + dprint(FD_IO, "prep: io_u %p: ret=%d\n", io_u, ret); + if (ret) unlock_file(td, io_u->file); return ret; @@ -276,11 +273,11 @@ out: return r; } -int td_io_queue(struct thread_data *td, struct io_u *io_u) +enum fio_q_status 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; + unsigned long long buflen = io_u->xfer_buflen; + enum fio_q_status ret; dprint_io_u(io_u, "queue"); fio_ro_check(td, io_u); @@ -288,6 +285,15 @@ int td_io_queue(struct thread_data *td, struct io_u *io_u) assert((io_u->flags & IO_U_F_FLIGHT) == 0); io_u_set(td, io_u, IO_U_F_FLIGHT); + /* + * If overlap checking was enabled in offload mode we + * can release this lock that was acquired when we + * started the overlap check because the IO_U_F_FLIGHT + * flag is now set + */ + if (td_offload_overlap(td)) + pthread_mutex_unlock(&overlap_check); + assert(fio_file_open(io_u->file)); /* @@ -298,7 +304,9 @@ int td_io_queue(struct thread_data *td, struct io_u *io_u) io_u->error = 0; io_u->resid = 0; - if (td_ioengine_flagged(td, FIO_SYNCIO)) { + if (td_ioengine_flagged(td, FIO_SYNCIO) || + (td_ioengine_flagged(td, FIO_ASYNCIO_SYNC_TRIM) && + io_u->ddir == DDIR_TRIM)) { if (fio_fill_issue_time(td)) fio_gettime(&io_u->issue_time, NULL); @@ -311,12 +319,15 @@ int td_io_queue(struct thread_data *td, struct io_u *io_u) } if (ddir_rw(ddir)) { - td->io_issues[ddir]++; - td->io_issue_bytes[ddir] += buflen; + if (!(io_u->flags & IO_U_F_VER_LIST)) { + 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); + zbd_queue_io_u(io_u, ret); unlock_file(td, io_u->file); @@ -348,32 +359,39 @@ int td_io_queue(struct thread_data *td, struct io_u *io_u) "invalid block size. Try setting direct=0.\n"); } - if (!td->io_ops->commit || io_u->ddir == DDIR_TRIM) { + if (zbd_unaligned_write(io_u->error) && + td->io_issues[io_u->ddir & 1] == 1 && + td->o.zone_mode != ZONE_MODE_ZBD) { + log_info("fio: first I/O failed. If %s is a zoned block device, consider --zonemode=zbd\n", + io_u->file->file_name); + } + + if (!td->io_ops->commit) { io_u_mark_submit(td, 1); io_u_mark_complete(td, 1); + zbd_put_io_u(io_u); } if (ret == FIO_Q_COMPLETED) { - if (ddir_rw(io_u->ddir)) { + if (ddir_rw(io_u->ddir) || + (ddir_sync(io_u->ddir) && td->runstate != TD_FSYNCING)) { io_u_mark_depth(td, 1); td->ts.total_io_u[io_u->ddir]++; } } else if (ret == FIO_Q_QUEUED) { - int r; - td->io_u_queued++; - if (ddir_rw(io_u->ddir)) + if (ddir_rw(io_u->ddir) || + (ddir_sync(io_u->ddir) && td->runstate != TD_FSYNCING)) td->ts.total_io_u[io_u->ddir]++; - if (td->io_u_queued >= td->o.iodepth_batch) { - r = td_io_commit(td); - if (r < 0) - return r; - } + if (td->io_u_queued >= td->o.iodepth_batch) + td_io_commit(td); } - if (!td_ioengine_flagged(td, FIO_SYNCIO)) { + if (!td_ioengine_flagged(td, FIO_SYNCIO) && + (!td_ioengine_flagged(td, FIO_ASYNCIO_SYNC_TRIM) || + io_u->ddir != DDIR_TRIM)) { if (fio_fill_issue_time(td)) fio_gettime(&io_u->issue_time, NULL); @@ -408,14 +426,14 @@ int td_io_init(struct thread_data *td) return ret; } -int td_io_commit(struct thread_data *td) +void td_io_commit(struct thread_data *td) { int ret; dprint(FD_IO, "calling ->commit(), depth %d\n", td->cur_depth); if (!td->cur_depth || !td->io_u_queued) - return 0; + return; io_u_mark_depth(td, td->io_u_queued); @@ -430,12 +448,18 @@ int td_io_commit(struct thread_data *td) */ td->io_u_in_flight += td->io_u_queued; td->io_u_queued = 0; - - return 0; } int td_io_open_file(struct thread_data *td, struct fio_file *f) { + if (fio_file_closing(f)) { + /* + * Open translates to undo closing. + */ + fio_file_clear_closing(f); + get_file(f); + return 0; + } assert(!fio_file_open(f)); assert(f->fd == -1); assert(td->io_ops->open_file); @@ -495,8 +519,8 @@ int td_io_open_file(struct thread_data *td, struct fio_file *f) } if (posix_fadvise(f->fd, f->file_offset, f->io_size, flags) < 0) { - td_verror(td, errno, "fadvise"); - goto err; + if (!fio_did_warn(FIO_WARN_FADVISE)) + log_err("fio: fadvise hint failed\n"); } } #ifdef FIO_HAVE_WRITE_HINT @@ -545,11 +569,6 @@ int td_io_close_file(struct thread_data *td, struct fio_file *f) */ fio_file_set_closing(f); - disk_util_dec(f->du); - - if (td->o.file_lock_mode != FILE_LOCK_NONE) - unlock_file_all(td, f); - return put_file(td, f); } @@ -579,6 +598,7 @@ int td_io_get_file_size(struct thread_data *td, struct fio_file *f) int fio_show_ioengine_help(const char *engine) { struct flist_head *entry; + struct thread_data td; struct ioengine_ops *io_ops; char *sep; int ret = 1; @@ -597,7 +617,10 @@ int fio_show_ioengine_help(const char *engine) sep++; } - io_ops = __load_ioengine(engine); + memset(&td, 0, sizeof(struct thread_data)); + td.o.ioengine = (char *)engine; + io_ops = load_ioengine(&td); + if (!io_ops) { log_info("IO engine %s not found\n", engine); return 1; @@ -608,5 +631,6 @@ int fio_show_ioengine_help(const char *engine) else log_info("IO engine %s has no options\n", io_ops->name); + free_ioengine(&td); return ret; }