Skip to content

Commit

Permalink
Add posixaio_waitcomplete engine.
Browse files Browse the repository at this point in the history
Provide a variant of the posixaio engine that uses FreeBSD's
aio_waitcomplete() function to consume completions, instead of running
around polling all IOs with aio_error().

Signed-off-by: Thomas Munro <[email protected]>
  • Loading branch information
macdice committed Aug 22, 2021
1 parent 15ce99b commit 7a7897a
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 0 deletions.
5 changes: 5 additions & 0 deletions HOWTO
Original file line number Diff line number Diff line change
Expand Up @@ -1945,6 +1945,11 @@ I/O engine
POSIX asynchronous I/O using :manpage:`aio_read(3)` and
:manpage:`aio_write(3)`.

**posixaio_waitcomplete**
POSIX asynchronous I/O, using FreeBSD's
aio_waitcomplete(2) to get completion events from the
kernel.

**solarisaio**
Solaris native asynchronous I/O.

Expand Down
23 changes: 23 additions & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,26 @@ EOF
fi
print_config "POSIX AIO fsync" "$posix_aio_fsync"

##########################################
# aio_waitcomplete probe
if test "have_aio_waitcomplete" != "yes" ; then
have_aio_waitcomplete="no"
fi
cat > $TMPC <<EOF
#include <aio.h>
#include <stdlib.h>
int main(void)
{
struct aiocb *cb;
aio_waitcomplete(&cb, NULL);
return 0;
}
EOF
if compile_prog "" "" "aio_waitcomplete" ; then
have_aio_waitcomplete="yes"
fi
print_config "aio_waitcomplete()" "$have_aio_waitcomplete"

##########################################
# POSIX pshared attribute probe
if test "$posix_pshared" != "yes" ; then
Expand Down Expand Up @@ -2858,6 +2878,9 @@ fi
if test "$posix_aio_fsync" = "yes" ; then
output_sym "CONFIG_POSIXAIO_FSYNC"
fi
if test "$have_aio_waitcomplete" = "yes" ; then
output_sym "CONFIG_HAVE_AIO_WAITCOMPLETE"
fi
if test "$posix_pshared" = "yes" ; then
output_sym "CONFIG_PSHARED"
fi
Expand Down
77 changes: 77 additions & 0 deletions engines/posixaio.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,59 @@ static int fio_posixaio_prep(struct thread_data fio_unused *td,
return 0;
}

#ifdef CONFIG_HAVE_AIO_WAITCOMPLETE

static int fio_posixaio_waitcomplete_getevents(struct thread_data *td,
unsigned int min,
unsigned int max,
const struct timespec *t)
{
struct posixaio_data *pd = td->io_ops_data;
struct aiocb *aiocb;
struct io_u *io_u;
ssize_t retval;
unsigned int events = 0;
struct timespec zero_timeout = {0};
struct timespec *timeout;

do
{
if (events < min) {
/* Wait until the minimum is satisfied. */
timeout = (struct timespec *)t;
} else {
/* Consume as many more as we can without waiting. */
timeout = &zero_timeout;
}

retval = aio_waitcomplete(&aiocb, timeout);
if (retval < 0) {
if (errno == EINTR)
continue;
if (errno == EAGAIN)
break;
td_verror(td, errno, "aio_waitcomplete");
break;
}

io_u = container_of(aiocb, struct io_u, aiocb);
pd->queued--;
pd->aio_events[events++] = io_u;

if (retval >= 0)
io_u->resid = io_u->xfer_buflen - retval;
else if (errno == ECANCELED)
io_u->resid = io_u->xfer_buflen;
else
io_u->error = errno;

} while (events < max && pd->queued > 0);

return events;
}

#endif

#define SUSPEND_ENTRIES 8

static int fio_posixaio_getevents(struct thread_data *td, unsigned int min,
Expand Down Expand Up @@ -223,12 +276,36 @@ static struct ioengine_ops ioengine = {
.get_file_size = generic_get_file_size,
};

#ifdef CONFIG_HAVE_AIO_WAITCOMPLETE
static struct ioengine_ops ioengine_waitcomplete = {
.name = "posixaio_waitcomplete",
.version = FIO_IOOPS_VERSION,
.flags = FIO_ASYNCIO_SYNC_TRIM,
.init = fio_posixaio_init,
.prep = fio_posixaio_prep,
.queue = fio_posixaio_queue,
.cancel = fio_posixaio_cancel,
.getevents = fio_posixaio_waitcomplete_getevents,
.event = fio_posixaio_event,
.cleanup = fio_posixaio_cleanup,
.open_file = generic_open_file,
.close_file = generic_close_file,
.get_file_size = generic_get_file_size,
};
#endif

static void fio_init fio_posixaio_register(void)
{
register_ioengine(&ioengine);
#ifdef CONFIG_HAVE_AIO_WAITCOMPLETE
register_ioengine(&ioengine_waitcomplete);
#endif
}

static void fio_exit fio_posixaio_unregister(void)
{
unregister_ioengine(&ioengine);
#ifdef CONFIG_HAVE_AIO_WAITCOMPLETE
unregister_ioengine(&ioengine_waitcomplete);
#endif
}
5 changes: 5 additions & 0 deletions fio.1
Original file line number Diff line number Diff line change
Expand Up @@ -1739,6 +1739,11 @@ This engine defines engine specific options.
POSIX asynchronous I/O using \fBaio_read\fR\|(3) and
\fBaio_write\fR\|(3).
.TP
.B posixaio_waitcomplete
POSIX asynchronous I/O using \fBaio_read\fR\|(3) and
\fBaio_write\fR\|(3), with FreeBSD \fBaio_waitcomplete\fR\|(2)
to consume completion events.
.TP
.B solarisaio
Solaris native asynchronous I/O.
.TP
Expand Down

0 comments on commit 7a7897a

Please sign in to comment.