X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=ioengines.c;h=e2316ee4e391d0d5899c960552fec4d19aa33ca2;hp=3e43ef2f9651dbd3b806af3c2c5a4046c4d36843;hb=c16dc793a3c45780f67ce65244b6e91323dee014;hpb=8bfe330eb42739d503d35d0b7d96f98c5c544204 diff --git a/ioengines.c b/ioengines.c index 3e43ef2f..e2316ee4 100644 --- a/ioengines.c +++ b/ioengines.c @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include "fio.h" #include "diskutil.h" @@ -22,6 +24,13 @@ static FLIST_HEAD(engine_list); +static inline bool async_ioengine_sync_trim(struct thread_data *td, + struct io_u *io_u) +{ + return td_ioengine_flagged(td, FIO_ASYNCIO_SYNC_TRIM) && + io_u->ddir == DDIR_TRIM; +} + static bool check_engine_ops(struct thread_data *td, struct ioengine_ops *ops) { if (ops->version != FIO_IOOPS_VERSION) { @@ -91,8 +100,9 @@ static void *dlopen_external(struct thread_data *td, const char *engine) char engine_path[PATH_MAX]; void *dlhandle; - sprintf(engine_path, "%s/lib%s.so", FIO_EXT_ENG_DIR, engine); + sprintf(engine_path, "%s/fio-%s.so", FIO_EXT_ENG_DIR, engine); + dprint(FD_IO, "dlopen external %s\n", engine_path); dlhandle = dlopen(engine_path, RTLD_LAZY); if (!dlhandle) log_info("Engine %s not found; Either name is invalid, was not built, or fio-engine-%s package is missing.\n", @@ -110,7 +120,11 @@ static struct ioengine_ops *dlopen_ioengine(struct thread_data *td, struct ioengine_ops *ops; void *dlhandle; - dprint(FD_IO, "dload engine %s\n", engine_lib); + if (!strncmp(engine_lib, "linuxaio", 8) || + !strncmp(engine_lib, "aio", 3)) + engine_lib = "libaio"; + + dprint(FD_IO, "dlopen engine %s\n", engine_lib); dlerror(); dlhandle = dlopen(engine_lib, RTLD_LAZY); @@ -149,7 +163,7 @@ static struct ioengine_ops *dlopen_ioengine(struct thread_data *td, return NULL; } - td->io_ops_dlhandle = dlhandle; + ops->dlhandle = dlhandle; return ops; } @@ -158,7 +172,7 @@ static struct ioengine_ops *__load_ioengine(const char *engine) /* * linux libaio has alias names, so convert to what we want */ - if (!strncmp(engine, "linuxaio", 8)) { + if (!strncmp(engine, "linuxaio", 8) || !strncmp(engine, "aio", 3)) { dprint(FD_IO, "converting ioengine name: %s -> libaio\n", engine); engine = "libaio"; @@ -188,7 +202,9 @@ struct ioengine_ops *load_ioengine(struct thread_data *td) * so as not to break job files not using the prefix. */ ops = __load_ioengine(td->o.ioengine); - if (!ops) + + /* We do re-dlopen existing handles, for reference counting */ + if (!ops || ops->dlhandle) ops = dlopen_ioengine(td, name); /* @@ -214,6 +230,8 @@ struct ioengine_ops *load_ioengine(struct thread_data *td) */ void free_ioengine(struct thread_data *td) { + assert(td != NULL && td->io_ops != NULL); + dprint(FD_IO, "free ioengine %s\n", td->io_ops->name); if (td->eo && td->io_ops->options) { @@ -222,9 +240,9 @@ void free_ioengine(struct thread_data *td) td->eo = NULL; } - if (td->io_ops_dlhandle) { - dlclose(td->io_ops_dlhandle); - td->io_ops_dlhandle = NULL; + if (td->io_ops->dlhandle) { + dprint(FD_IO, "dlclose ioengine %s\n", td->io_ops->name); + dlclose(td->io_ops->dlhandle); } td->io_ops = NULL; @@ -339,17 +357,17 @@ enum fio_q_status td_io_queue(struct thread_data *td, struct io_u *io_u) io_u->resid = 0; 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)) + async_ioengine_sync_trim(td, io_u)) { + if (fio_fill_issue_time(td)) { fio_gettime(&io_u->issue_time, NULL); - /* - * only used for iolog - */ - if (td->o.read_iolog_file) - memcpy(&td->last_issue, &io_u->issue_time, - sizeof(io_u->issue_time)); + /* + * only used for iolog + */ + if (td->o.read_iolog_file) + memcpy(&td->last_issue, &io_u->issue_time, + sizeof(io_u->issue_time)); + } } @@ -404,7 +422,6 @@ enum fio_q_status td_io_queue(struct thread_data *td, struct io_u *io_u) if (!td->io_ops->commit) { io_u_mark_submit(td, 1); io_u_mark_complete(td, 1); - zbd_put_io_u(td, io_u); } if (ret == FIO_Q_COMPLETED) { @@ -425,17 +442,18 @@ enum fio_q_status td_io_queue(struct thread_data *td, struct io_u *io_u) } 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)) + !async_ioengine_sync_trim(td, io_u)) { + if (fio_fill_issue_time(td) && + !td_ioengine_flagged(td, FIO_ASYNCIO_SETS_ISSUE_TIME)) { fio_gettime(&io_u->issue_time, NULL); - /* - * only used for iolog - */ - if (td->o.read_iolog_file) - memcpy(&td->last_issue, &io_u->issue_time, - sizeof(io_u->issue_time)); + /* + * only used for iolog + */ + if (td->o.read_iolog_file) + memcpy(&td->last_issue, &io_u->issue_time, + sizeof(io_u->issue_time)); + } } return ret; @@ -630,6 +648,34 @@ int td_io_get_file_size(struct thread_data *td, struct fio_file *f) return td->io_ops->get_file_size(td, f); } +#ifdef CONFIG_DYNAMIC_ENGINES +/* Load all dynamic engines in FIO_EXT_ENG_DIR for enghelp command */ +static void +fio_load_dynamic_engines(struct thread_data *td) +{ + DIR *dirhandle = NULL; + struct dirent *dirent = NULL; + char engine_path[PATH_MAX]; + + dirhandle = opendir(FIO_EXT_ENG_DIR); + if (!dirhandle) + return; + + while ((dirent = readdir(dirhandle)) != NULL) { + if (!strcmp(dirent->d_name, ".") || + !strcmp(dirent->d_name, "..")) + continue; + + sprintf(engine_path, "%s/%s", FIO_EXT_ENG_DIR, dirent->d_name); + dlopen_ioengine(td, engine_path); + } + + closedir(dirhandle); +} +#else +#define fio_load_dynamic_engines(td) do { } while (0) +#endif + int fio_show_ioengine_help(const char *engine) { struct flist_head *entry; @@ -638,8 +684,11 @@ int fio_show_ioengine_help(const char *engine) char *sep; int ret = 1; + memset(&td, 0, sizeof(struct thread_data)); + if (!engine || !*engine) { log_info("Available IO engines:\n"); + fio_load_dynamic_engines(&td); flist_for_each(entry, &engine_list) { io_ops = flist_entry(entry, struct ioengine_ops, list); log_info("\t%s\n", io_ops->name); @@ -652,19 +701,18 @@ int fio_show_ioengine_help(const char *engine) sep++; } - memset(&td, 0, sizeof(struct thread_data)); td.o.ioengine = (char *)engine; - io_ops = load_ioengine(&td); + td.io_ops = load_ioengine(&td); - if (!io_ops) { + if (!td.io_ops) { log_info("IO engine %s not found\n", engine); return 1; } - if (io_ops->options) - ret = show_cmd_help(io_ops->options, sep); + if (td.io_ops->options) + ret = show_cmd_help(td.io_ops->options, sep); else - log_info("IO engine %s has no options\n", io_ops->name); + log_info("IO engine %s has no options\n", td.io_ops->name); free_ioengine(&td); return ret;