From 74c7a04ecc0a2ad88def229d80b1f86dd2d094c9 Mon Sep 17 00:00:00 2001 Message-Id: <74c7a04ecc0a2ad88def229d80b1f86dd2d094c9.1427300678.git.jen@redhat.com> In-Reply-To: References: From: Vlad Yasevich Date: Thu, 12 Mar 2015 19:13:19 -0500 Subject: [CHANGE 23/33] aio: convert aio_poll() to g_poll(3) To: rhvirt-patches@redhat.com, jen@redhat.com RH-Author: Vlad Yasevich Message-id: <1426187601-21396-24-git-send-email-vyasevic@redhat.com> Patchwork-id: 64363 O-Subject: [RHEL6.7 qemu-kvm PATCH v2 23/25] aio: convert aio_poll() to g_poll(3) Bugzilla: 1005016 RH-Acked-by: Juan Quintela RH-Acked-by: Michael S. Tsirkin RH-Acked-by: Paolo Bonzini From: Stefan Hajnoczi AioHandler already has a GPollFD so we can directly use its events/revents. Add the int pollfds_idx field to AioContext so we can map g_poll(3) results back to AioHandlers. Reuse aio_dispatch() to invoke handlers after g_poll(3). Signed-off-by: Stefan Hajnoczi Reviewed-by: Laszlo Ersek Message-id: 1361356113-11049-10-git-send-email-stefanha@redhat.com Signed-off-by: Anthony Liguori (cherry picked from commit 6b5f876252b7aeec43e319afdf17705f512be2bc) Signed-off-by: Jeff E. Nelson Conflicts: async.c - introduce a tiny aio_finilize that cleans up the fd array. include/block/aio.h - Doesn't exist. Changes went into qemu-aio.h Signed-off-by: Vladislav Yasevich --- aio-posix.c | 67 ++++++++++++++++++++++--------------------------------------- async.c | 15 ++++++++++++-- qemu-aio.h | 3 +++ 3 files changed, 40 insertions(+), 45 deletions(-) Signed-off-by: Jeff E. Nelson --- aio-posix.c | 67 ++++++++++++++++++++++--------------------------------------- async.c | 15 ++++++++++++-- qemu-aio.h | 3 +++ 3 files changed, 40 insertions(+), 45 deletions(-) diff --git a/aio-posix.c b/aio-posix.c index 154048d..5387268 100644 --- a/aio-posix.c +++ b/aio-posix.c @@ -23,6 +23,7 @@ struct AioHandler IOHandler *io_write; AioFlushHandler *io_flush; int deleted; + int pollfds_idx; void *opaque; QLIST_ENTRY(AioHandler) node; }; @@ -83,6 +84,7 @@ void aio_set_fd_handler(AioContext *ctx, node->io_write = io_write; node->io_flush = io_flush; node->opaque = opaque; + node->pollfds_idx = -1; node->pfd.events = (io_read ? G_IO_IN | G_IO_HUP : 0); node->pfd.events |= (io_write ? G_IO_OUT : 0); @@ -164,10 +166,7 @@ static bool aio_dispatch(AioContext *ctx) bool aio_poll(AioContext *ctx, bool blocking) { - static struct timeval tv0; AioHandler *node; - fd_set rdfds, wrfds; - int max_fd = -1; int ret; bool busy, progress; @@ -193,12 +192,13 @@ bool aio_poll(AioContext *ctx, bool blocking) ctx->walking_handlers++; - FD_ZERO(&rdfds); - FD_ZERO(&wrfds); + g_array_set_size(ctx->pollfds, 0); - /* fill fd sets */ + /* fill pollfds */ busy = false; QLIST_FOREACH(node, &ctx->aio_handlers, node) { + node->pollfds_idx = -1; + /* If there aren't pending AIO operations, don't invoke callbacks. * Otherwise, if there are no AIO requests, qemu_aio_wait() would * wait indefinitely. @@ -209,13 +209,13 @@ bool aio_poll(AioContext *ctx, bool blocking) } busy = true; } - if (!node->deleted && node->io_read) { - FD_SET(node->pfd.fd, &rdfds); - max_fd = MAX(max_fd, node->pfd.fd + 1); - } - if (!node->deleted && node->io_write) { - FD_SET(node->pfd.fd, &wrfds); - max_fd = MAX(max_fd, node->pfd.fd + 1); + if (!node->deleted && node->pfd.events) { + GPollFD pfd = { + .fd = node->pfd.fd, + .events = node->pfd.events, + }; + node->pollfds_idx = ctx->pollfds->len; + g_array_append_val(ctx->pollfds, pfd); } } @@ -227,41 +227,22 @@ bool aio_poll(AioContext *ctx, bool blocking) } /* wait until next event */ - ret = select(max_fd, &rdfds, &wrfds, NULL, blocking ? NULL : &tv0); + ret = g_poll((GPollFD *)ctx->pollfds->data, + ctx->pollfds->len, + blocking ? -1 : 0); /* if we have any readable fds, dispatch event */ if (ret > 0) { - /* we have to walk very carefully in case - * qemu_aio_set_fd_handler is called while we're walking */ - node = QLIST_FIRST(&ctx->aio_handlers); - while (node) { - AioHandler *tmp; - - ctx->walking_handlers++; - - if (!node->deleted && - FD_ISSET(node->pfd.fd, &rdfds) && - node->io_read) { - node->io_read(node->opaque); - progress = true; - } - if (!node->deleted && - FD_ISSET(node->pfd.fd, &wrfds) && - node->io_write) { - node->io_write(node->opaque); - progress = true; - } - - tmp = node; - node = QLIST_NEXT(node, node); - - ctx->walking_handlers--; - - if (!ctx->walking_handlers && tmp->deleted) { - QLIST_REMOVE(tmp, node); - g_free(tmp); + QLIST_FOREACH(node, &ctx->aio_handlers, node) { + if (node->pollfds_idx != -1) { + GPollFD *pfd = &g_array_index(ctx->pollfds, GPollFD, + node->pollfds_idx); + node->pfd.revents = pfd->revents; } } + if (aio_dispatch(ctx)) { + progress = true; + } } return progress; diff --git a/async.c b/async.c index d6e1643..530333e 100644 --- a/async.c +++ b/async.c @@ -177,11 +177,19 @@ aio_ctx_dispatch(GSource *source, return true; } +static void +aio_ctx_finalize(GSource *source) +{ + AioContext *ctx = (AioContext *) source; + + g_array_free(ctx->pollfds, TRUE); +} + static GSourceFuncs aio_source_funcs = { aio_ctx_prepare, aio_ctx_check, aio_ctx_dispatch, - NULL + aio_ctx_finalize, }; GSource *aio_get_g_source(AioContext *ctx) @@ -192,7 +200,10 @@ GSource *aio_get_g_source(AioContext *ctx) AioContext *aio_context_new(void) { - return (AioContext *) g_source_new(&aio_source_funcs, sizeof(AioContext)); + AioContext *ctx; + ctx = (AioContext *) g_source_new(&aio_source_funcs, sizeof(AioContext)); + ctx->pollfds = g_array_new(FALSE, FALSE, sizeof(GPollFD)); + return ctx; } void aio_context_ref(AioContext *ctx) diff --git a/qemu-aio.h b/qemu-aio.h index b3c5b2a..540ef81 100644 --- a/qemu-aio.h +++ b/qemu-aio.h @@ -61,6 +61,9 @@ typedef struct AioContext { * no callbacks are removed while we're walking and dispatching callbacks. */ int walking_bh; + + /* GPollFDs for aio_poll() */ + GArray *pollfds; } AioContext; /* Returns 1 if there are still outstanding AIO requests; 0 otherwise */ -- 2.1.0