diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2014-07-14 13:09:29 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2014-07-14 13:09:29 +0100 |
commit | 7a6d04e73fdd571234e05dcad96895fafb3f22f0 (patch) | |
tree | acf7065c975ca4056f3041c58907803239b9941e /aio-posix.c | |
parent | c15a34eda0f270888a0e4676997317e1bd7894b8 (diff) | |
parent | 58ac321135af890b503ebe56d0d00e184779918f (diff) | |
download | hqemu-7a6d04e73fdd571234e05dcad96895fafb3f22f0.zip hqemu-7a6d04e73fdd571234e05dcad96895fafb3f22f0.tar.gz |
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block patches for 2.1.0-rc2 (v2)
# gpg: Signature made Mon 14 Jul 2014 11:04:12 BST using RSA key ID C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"
* remotes/kevin/tags/for-upstream: (22 commits)
ide: Treat read/write beyond end as invalid
virtio-blk: Treat read/write beyond end as invalid
virtio-blk: Bypass error action and I/O accounting on invalid r/w
virtio-blk: Factor common checks out of virtio_blk_handle_read/write()
dma-helpers: Fix too long qiov
qtest: fix vhost-user-test compilation with old GLib
tests: Fix unterminated string output visitor enum human string
AioContext: do not rely on aio_poll(ctx, true) result to end a loop
virtio-blk: embed VirtQueueElement in VirtIOBlockReq
virtio-blk: avoid g_slice_new0() for VirtIOBlockReq and VirtQueueElement
dataplane: do not free VirtQueueElement in vring_push()
virtio-blk: avoid dataplane VirtIOBlockReq early free
block: Assert qiov length matches request length
qed: Make qiov match request size until backing file EOF
qcow2: Make qiov match request size until backing file EOF
block: Make qiov match the request size until EOF
AioContext: speed up aio_notify
test-aio: fix GSource-based timer test
block: drop aio functions that operate on the main AioContext
block: prefer aio_poll to qemu_aio_wait
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'aio-posix.c')
-rw-r--r-- | aio-posix.c | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/aio-posix.c b/aio-posix.c index f921d4f..2eada2e 100644 --- a/aio-posix.c +++ b/aio-posix.c @@ -125,7 +125,7 @@ static bool aio_dispatch(AioContext *ctx) bool progress = false; /* - * We have to walk very carefully in case qemu_aio_set_fd_handler is + * We have to walk very carefully in case aio_set_fd_handler is * called while we're walking. */ node = QLIST_FIRST(&ctx->aio_handlers); @@ -175,27 +175,56 @@ static bool aio_dispatch(AioContext *ctx) bool aio_poll(AioContext *ctx, bool blocking) { AioHandler *node; + bool was_dispatching; int ret; bool progress; + was_dispatching = ctx->dispatching; progress = false; + /* aio_notify can avoid the expensive event_notifier_set if + * everything (file descriptors, bottom halves, timers) will + * be re-evaluated before the next blocking poll(). This happens + * in two cases: + * + * 1) when aio_poll is called with blocking == false + * + * 2) when we are called after poll(). If we are called before + * poll(), bottom halves will not be re-evaluated and we need + * aio_notify() if blocking == true. + * + * The first aio_dispatch() only does something when AioContext is + * running as a GSource, and in that case aio_poll is used only + * with blocking == false, so this optimization is already quite + * effective. However, the code is ugly and should be restructured + * to have a single aio_dispatch() call. To do this, we need to + * reorganize aio_poll into a prepare/poll/dispatch model like + * glib's. + * + * If we're in a nested event loop, ctx->dispatching might be true. + * In that case we can restore it just before returning, but we + * have to clear it now. + */ + aio_set_dispatching(ctx, !blocking); + /* * If there are callbacks left that have been queued, we need to call them. * Do not call select in this case, because it is possible that the caller - * does not need a complete flush (as is the case for qemu_aio_wait loops). + * does not need a complete flush (as is the case for aio_poll loops). */ if (aio_bh_poll(ctx)) { blocking = false; progress = true; } + /* Re-evaluate condition (1) above. */ + aio_set_dispatching(ctx, !blocking); if (aio_dispatch(ctx)) { progress = true; } if (progress && !blocking) { - return true; + goto out; } ctx->walking_handlers++; @@ -234,9 +263,12 @@ bool aio_poll(AioContext *ctx, bool blocking) } /* Run dispatch even if there were no readable fds to run timers */ + aio_set_dispatching(ctx, true); if (aio_dispatch(ctx)) { progress = true; } +out: + aio_set_dispatching(ctx, was_dispatching); return progress; } |