aio: enable polling for IOCTX_FLAG_SQTHREAD
authorJens Axboe <axboe@kernel.dk>
Fri, 4 Jan 2019 19:49:19 +0000 (12:49 -0700)
committerJens Axboe <axboe@kernel.dk>
Sun, 6 Jan 2019 21:57:16 +0000 (14:57 -0700)
commit541a919e90b44c8d7f4376dd6969ebddb7fe7091
treea1bba6596f3afb9739bc87de24ec0726ed122861
parent858321a87604d5f3ec95cf37044a8a8e3d223d51
aio: enable polling for IOCTX_FLAG_SQTHREAD

This enables an application to do IO, without ever entering the kernel.
By using the SQ ring to fill in new events and watching for completions
on the CQ ring, we can submit and reap IOs without doing a single system
call. The kernel side thread will poll for new submissions, and in case
of HIPRI/polled IO, it'll also poll for completions.

For O_DIRECT, we can do this with just SQTHREAD being enabled. For
buffered aio, we need the workqueue as well. If we can satisfy the
buffered inline from the SQTHREAD, we do that. If not, we punt to the
workqueue. This is just like buffered aio off the io_uring_enter(2)
system call.

Proof of concept. If the thread has been idle for 1 second, it will set
sq_ring->flags |= IORING_SQ_NEED_WAKEUP. The application will have to
call io_uring_enter() to start things back up again. If IO is kept busy,
that will never be needed. Basically an application that has this
feature enabled will guard it's io_uring_enter(2) call with:

barrier();
if (sq_ring->flags & IORING_SQ_NEED_WAKEUP)
io_uring_enter(fd, to_submit, 0, 0);

instead of calling it unconditionally.

Improvements:

1) Maybe have smarter backoff. Busy loop for X time, then go to
   monitor/mwait, finally the schedule we have now after an idle
   second. Might not be worth the complexity.

2) Probably want the application to pass in the appropriate grace
   period, not hard code it at 1 second.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
fs/aio.c
include/uapi/linux/aio_abi.h