X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=engines%2Flibaio.c;h=33b8c12f96fb191af478114d1a1feb563ffb0440;hp=b909b79e9c7169f7898e2aa32be37f895cafe4a0;hb=HEAD;hpb=fa443634fbfa38fd5d6418a96a45022c78b90df4 diff --git a/engines/libaio.c b/engines/libaio.c index b909b79e..aaccc7ce 100644 --- a/engines/libaio.c +++ b/engines/libaio.c @@ -15,6 +15,7 @@ #include "../lib/pow2.h" #include "../optgroup.h" #include "../lib/memalign.h" +#include "cmdprio.h" /* Should be defined in newest aio_abi.h */ #ifndef IOCB_FLAG_IOPRIO @@ -50,12 +51,14 @@ struct libaio_data { unsigned int queued; unsigned int head; unsigned int tail; + + struct cmdprio cmdprio; }; struct libaio_options { - void *pad; + struct thread_data *td; unsigned int userspace_reap; - unsigned int cmdprio_percentage; + struct cmdprio_options cmdprio_options; unsigned int nowait; }; @@ -69,26 +72,6 @@ static struct fio_option options[] = { .category = FIO_OPT_C_ENGINE, .group = FIO_OPT_G_LIBAIO, }, -#ifdef FIO_HAVE_IOPRIO_CLASS - { - .name = "cmdprio_percentage", - .lname = "high priority percentage", - .type = FIO_OPT_INT, - .off1 = offsetof(struct libaio_options, cmdprio_percentage), - .minval = 1, - .maxval = 100, - .help = "Send high priority I/O this percentage of the time", - .category = FIO_OPT_C_ENGINE, - .group = FIO_OPT_G_LIBAIO, - }, -#else - { - .name = "cmdprio_percentage", - .lname = "high priority percentage", - .type = FIO_OPT_UNSUPPORTED, - .help = "Your platform does not support I/O priority classes", - }, -#endif { .name = "nowait", .lname = "RWF_NOWAIT", @@ -98,6 +81,7 @@ static struct fio_option options[] = { .category = FIO_OPT_C_ENGINE, .group = FIO_OPT_G_LIBAIO, }, + CMDPRIO_OPTIONS(struct libaio_options, FIO_OPT_G_LIBAIO), { .name = NULL, }, @@ -132,15 +116,16 @@ static int fio_libaio_prep(struct thread_data *td, struct io_u *io_u) return 0; } -static void fio_libaio_prio_prep(struct thread_data *td, struct io_u *io_u) +static inline void fio_libaio_cmdprio_prep(struct thread_data *td, + struct io_u *io_u) { - struct libaio_options *o = td->eo; - if (rand_between(&td->prio_state, 0, 99) < o->cmdprio_percentage) { - io_u->iocb.aio_reqprio = IOPRIO_CLASS_RT << IOPRIO_CLASS_SHIFT; + struct libaio_data *ld = td->io_ops_data; + struct cmdprio *cmdprio = &ld->cmdprio; + + if (fio_cmdprio_set_ioprio(td, cmdprio, io_u)) { + io_u->iocb.aio_reqprio = io_u->ioprio; io_u->iocb.u.c.flags |= IOCB_FLAG_IOPRIO; - io_u->flags |= IO_U_F_PRIORITY; } - return; } static struct io_u *fio_libaio_event(struct thread_data *td, int event) @@ -223,14 +208,16 @@ static int fio_libaio_getevents(struct thread_data *td, unsigned int min, && actual_min == 0 && ((struct aio_ring *)(ld->aio_ctx))->magic == AIO_RING_MAGIC) { - r = user_io_getevents(ld->aio_ctx, max, + r = user_io_getevents(ld->aio_ctx, max - events, ld->aio_events + events); } else { r = io_getevents(ld->aio_ctx, actual_min, - max, ld->aio_events + events, lt); + max - events, ld->aio_events + events, lt); } - if (r > 0) + if (r > 0) { events += r; + actual_min -= min((unsigned int)events, actual_min); + } else if ((min && r == 0) || r == -EAGAIN) { fio_libaio_commit(td); if (actual_min) @@ -246,7 +233,6 @@ static enum fio_q_status fio_libaio_queue(struct thread_data *td, struct io_u *io_u) { struct libaio_data *ld = td->io_ops_data; - struct libaio_options *o = td->eo; fio_ro_check(td, io_u); @@ -277,8 +263,8 @@ static enum fio_q_status fio_libaio_queue(struct thread_data *td, return FIO_Q_COMPLETED; } - if (o->cmdprio_percentage) - fio_libaio_prio_prep(td, io_u); + if (ld->cmdprio.mode != CMDPRIO_MODE_NONE) + fio_libaio_cmdprio_prep(td, io_u); ld->iocbs[ld->head] = &io_u->iocb; ld->io_us[ld->head] = io_u; @@ -304,6 +290,12 @@ static void fio_libaio_queued(struct thread_data *td, struct io_u **io_us, memcpy(&io_u->issue_time, &now, sizeof(now)); io_u_queued(td, io_u); } + + /* + * only used for iolog + */ + if (td->o.read_iolog_file) + memcpy(&td->last_issue, &now, sizeof(now)); } static int fio_libaio_commit(struct thread_data *td) @@ -396,6 +388,8 @@ static void fio_libaio_cleanup(struct thread_data *td) */ if (!(td->flags & TD_F_CHILD)) io_destroy(ld->aio_ctx); + + fio_cmdprio_cleanup(&ld->cmdprio); free(ld->aio_events); free(ld->iocbs); free(ld->io_us); @@ -420,8 +414,8 @@ static int fio_libaio_post_init(struct thread_data *td) static int fio_libaio_init(struct thread_data *td) { struct libaio_data *ld; - struct thread_options *to = &td->o; struct libaio_options *o = td->eo; + int ret; ld = calloc(1, sizeof(*ld)); @@ -432,23 +426,21 @@ static int fio_libaio_init(struct thread_data *td) ld->io_us = calloc(ld->entries, sizeof(struct io_u *)); td->io_ops_data = ld; - /* - * Check for option conflicts - */ - if ((fio_option_is_set(to, ioprio) || fio_option_is_set(to, ioprio_class)) && - o->cmdprio_percentage != 0) { - log_err("%s: cmdprio_percentage option and mutually exclusive " - "prio or prioclass option is set, exiting\n", to->name); + + ret = fio_cmdprio_init(td, &ld->cmdprio, &o->cmdprio_options); + if (ret) { td_verror(td, EINVAL, "fio_libaio_init"); return 1; } + return 0; } FIO_STATIC struct ioengine_ops ioengine = { .name = "libaio", .version = FIO_IOOPS_VERSION, - .flags = FIO_ASYNCIO_SYNC_TRIM, + .flags = FIO_ASYNCIO_SYNC_TRIM | + FIO_ASYNCIO_SETS_ISSUE_TIME, .init = fio_libaio_init, .post_init = fio_libaio_post_init, .prep = fio_libaio_prep,