From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 5/7] aio: return "AIO in progress" state from qemu_aio_wait
Date: Mon, 12 Mar 2012 19:22:26 +0100 [thread overview]
Message-ID: <1331576548-23067-6-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1331576548-23067-1-git-send-email-pbonzini@redhat.com>
The definition of when qemu_aio_flush should loop is much simpler
than it looks. It just has to call qemu_aio_wait until it makes
no progress and all flush callbacks return false. qemu_aio_wait
is the logical place to tell the caller about this, and the return
code will also help implementing bdrv_drain.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
aio.c | 48 ++++++++++++++++++++++--------------------------
qemu-aio.h | 6 ++++--
2 files changed, 26 insertions(+), 28 deletions(-)
diff --git a/aio.c b/aio.c
index f19b3c6..71264fc 100644
--- a/aio.c
+++ b/aio.c
@@ -99,41 +99,30 @@ int qemu_aio_set_fd_handler(int fd,
void qemu_aio_flush(void)
{
- AioHandler *node;
- int ret;
-
- do {
- ret = 0;
-
- /*
- * If there are pending emulated aio start them now so flush
- * will be able to return 1.
- */
- qemu_aio_wait();
-
- QLIST_FOREACH(node, &aio_handlers, node) {
- if (node->io_flush) {
- ret |= node->io_flush(node->opaque);
- }
- }
- } while (qemu_bh_poll() || ret > 0);
+ /* Always poll at least once; bottom halves may start new AIO so
+ * flush will be able to return 1. However, they also might not :)
+ * so only block starting from the second call.
+ */
+ while (qemu_aio_wait());
}
-void qemu_aio_wait(void)
+bool qemu_aio_wait(void)
{
int ret;
/*
* If there are callbacks left that have been queued, we need to call then.
- * Return afterwards to avoid waiting needlessly in select().
+ * 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).
*/
if (qemu_bh_poll()) {
- return;
+ return true;
}
do {
AioHandler *node;
fd_set rdfds, wrfds;
+ bool busy;
int max_fd = -1;
walking_handlers = 1;
@@ -142,14 +131,18 @@ void qemu_aio_wait(void)
FD_ZERO(&wrfds);
/* fill fd sets */
+ busy = false;
QLIST_FOREACH(node, &aio_handlers, node) {
/* If there aren't pending AIO operations, don't invoke callbacks.
* Otherwise, if there are no AIO requests, qemu_aio_wait() would
* wait indefinitely.
*/
- if (node->io_flush && node->io_flush(node->opaque) == 0)
- continue;
-
+ if (node->io_flush) {
+ if (node->io_flush(node->opaque) == 0) {
+ continue;
+ }
+ busy = true;
+ }
if (!node->deleted && node->io_read) {
FD_SET(node->fd, &rdfds);
max_fd = MAX(max_fd, node->fd + 1);
@@ -163,8 +156,9 @@ void qemu_aio_wait(void)
walking_handlers = 0;
/* No AIO operations? Get us out of here */
- if (max_fd == -1)
- break;
+ if (!busy) {
+ return false;
+ }
/* wait until next event */
ret = select(max_fd, &rdfds, &wrfds, NULL, NULL);
@@ -204,4 +198,6 @@ void qemu_aio_wait(void)
walking_handlers = 0;
}
} while (ret == 0);
+
+ return true;
}
diff --git a/qemu-aio.h b/qemu-aio.h
index 0fc8409..bfdd35f 100644
--- a/qemu-aio.h
+++ b/qemu-aio.h
@@ -48,8 +48,10 @@ void qemu_aio_flush(void);
/* Wait for a single AIO completion to occur. This function will wait
* until a single AIO event has completed and it will ensure something
* has moved before returning. This can issue new pending aio as
- * result of executing I/O completion or bh callbacks. */
-void qemu_aio_wait(void);
+ * result of executing I/O completion or bh callbacks.
+ *
+ * Return whether there is still any pending AIO operation. */
+bool qemu_aio_wait(void);
/* Register a file descriptor and associated callbacks. Behaves very similarly
* to qemu_set_fd_handler2. Unlike qemu_set_fd_handler2, these callbacks will
--
1.7.7.6
next prev parent reply other threads:[~2012-03-12 18:23 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-03-12 18:22 [Qemu-devel] [PATCH 0/7] AIO nested loop and bdrv_drain_all changes Paolo Bonzini
2012-03-12 18:22 ` [Qemu-devel] [PATCH 1/7] qemu-io: use main_loop_wait Paolo Bonzini
2012-03-12 18:22 ` [Qemu-devel] [PATCH 2/7] qemu-tool: map vm_clock to rt_clock Paolo Bonzini
2012-03-12 18:22 ` [Qemu-devel] [PATCH 3/7] posix-aio: merge posix_aio_process_queue and posix_aio_read Paolo Bonzini
2012-03-12 18:22 ` [Qemu-devel] [PATCH 4/7] aio: remove process_queue callback and qemu_aio_process_queue Paolo Bonzini
2012-03-12 18:22 ` Paolo Bonzini [this message]
2012-03-12 18:22 ` [Qemu-devel] [PATCH 6/7] aio: simplify qemu_aio_wait Paolo Bonzini
2012-03-12 18:22 ` [Qemu-devel] [PATCH 7/7] block: add the support to drain throttled requests Paolo Bonzini
2012-03-13 1:38 ` Zhi Yong Wu
2012-03-13 1:46 ` Zhi Yong Wu
2012-03-13 1:56 ` Zhi Yong Wu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1331576548-23067-6-git-send-email-pbonzini@redhat.com \
--to=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).