diff options
author | Stefan Hajnoczi | 2020-03-05 18:08:02 +0100 |
---|---|---|
committer | Stefan Hajnoczi | 2020-03-09 17:41:31 +0100 |
commit | 1f050a4690f62a1e7dabc4f44141e9f762c3769f (patch) | |
tree | 289c3970dfed15773b4a6cc234d2c580f28ef189 /include/block | |
parent | aio-posix: move RCU_READ_LOCK() into run_poll_handlers() (diff) | |
download | qemu-1f050a4690f62a1e7dabc4f44141e9f762c3769f.tar.gz qemu-1f050a4690f62a1e7dabc4f44141e9f762c3769f.tar.xz qemu-1f050a4690f62a1e7dabc4f44141e9f762c3769f.zip |
aio-posix: extract ppoll(2) and epoll(7) fd monitoring
The ppoll(2) and epoll(7) file descriptor monitoring implementations are
mixed with the core util/aio-posix.c code. Before adding another
implementation for Linux io_uring, extract out the existing
ones so there is a clear interface and the core code is simpler.
The new interface is AioContext->fdmon_ops, a pointer to a FDMonOps
struct. See the patch for details.
Semantic changes:
1. ppoll(2) now reflects events from pollfds[] back into AioHandlers
while we're still on the clock for adaptive polling. This was
already happening for epoll(7), so if it's really an issue then we'll
need to fix both in the future.
2. epoll(7)'s fallback to ppoll(2) while external events are disabled
was broken when the number of fds exceeded the epoll(7) upgrade
threshold. I guess this code path simply wasn't tested and no one
noticed the bug. I didn't go out of my way to fix it but the correct
code is simpler than preserving the bug.
I also took some liberties in removing the unnecessary
AioContext->epoll_available (just check AioContext->epollfd != -1
instead) and AioContext->epoll_enabled (it's implicit if our
AioContext->fdmon_ops callbacks are being invoked) fields.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Link: https://lore.kernel.org/r/20200305170806.1313245-4-stefanha@redhat.com
Message-Id: <20200305170806.1313245-4-stefanha@redhat.com>
Diffstat (limited to 'include/block')
-rw-r--r-- | include/block/aio.h | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/include/block/aio.h b/include/block/aio.h index 9dd61cee7e..90e07d7507 100644 --- a/include/block/aio.h +++ b/include/block/aio.h @@ -52,6 +52,38 @@ struct ThreadPool; struct LinuxAioState; struct LuringState; +/* Callbacks for file descriptor monitoring implementations */ +typedef struct { + /* + * update: + * @ctx: the AioContext + * @node: the handler + * @is_new: is the file descriptor already being monitored? + * + * Add/remove/modify a monitored file descriptor. There are three cases: + * 1. node->pfd.events == 0 means remove the file descriptor. + * 2. !is_new means modify an already monitored file descriptor. + * 3. is_new means add a new file descriptor. + * + * Called with ctx->list_lock acquired. + */ + void (*update)(AioContext *ctx, AioHandler *node, bool is_new); + + /* + * wait: + * @ctx: the AioContext + * @ready_list: list for handlers that become ready + * @timeout: maximum duration to wait, in nanoseconds + * + * Wait for file descriptors to become ready and place them on ready_list. + * + * Called with ctx->list_lock incremented but not locked. + * + * Returns: number of ready file descriptors. + */ + int (*wait)(AioContext *ctx, AioHandlerList *ready_list, int64_t timeout); +} FDMonOps; + /* * Each aio_bh_poll() call carves off a slice of the BH list, so that newly * scheduled BHs are not processed until the next aio_bh_poll() call. All @@ -173,8 +205,8 @@ struct AioContext { /* epoll(7) state used when built with CONFIG_EPOLL */ int epollfd; - bool epoll_enabled; - bool epoll_available; + + const FDMonOps *fdmon_ops; }; /** |