aboutsummaryrefslogtreecommitdiff
path: root/include/block/aio-wait.h
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2020-04-07 10:07:45 -0400
committerStefan Hajnoczi <stefanha@redhat.com>2020-04-09 16:16:28 +0100
commit3c18a92dc4b55ca8cc37a755ed119f11c0f34099 (patch)
tree1153ea1812c170bcc50e72820bae2d585827c0a0 /include/block/aio-wait.h
parent636b836d5f4e36ceebb788e2e0d4724f7f9406e1 (diff)
aio-wait: delegate polling of main AioContext if BQL not held
Any thread that is not a iothread returns NULL for qemu_get_current_aio_context(). As a result, it would also return true for in_aio_context_home_thread(qemu_get_aio_context()), causing AIO_WAIT_WHILE to invoke aio_poll() directly. This is incorrect if the BQL is not held, because aio_poll() does not expect to run concurrently from multiple threads, and it can actually happen when savevm writes to the vmstate file from the migration thread. Therefore, restrict in_aio_context_home_thread to return true for the main AioContext only if the BQL is held. The function is moved to aio-wait.h because it is mostly used there and to avoid a circular reference between main-loop.h and block/aio.h. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Message-Id: <20200407140746.8041-5-pbonzini@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'include/block/aio-wait.h')
-rw-r--r--include/block/aio-wait.h22
1 files changed, 22 insertions, 0 deletions
diff --git a/include/block/aio-wait.h b/include/block/aio-wait.h
index afeeb18f95..716d2639df 100644
--- a/include/block/aio-wait.h
+++ b/include/block/aio-wait.h
@@ -26,6 +26,7 @@
#define QEMU_AIO_WAIT_H
#include "block/aio.h"
+#include "qemu/main-loop.h"
/**
* AioWait:
@@ -124,4 +125,25 @@ void aio_wait_kick(void);
*/
void aio_wait_bh_oneshot(AioContext *ctx, QEMUBHFunc *cb, void *opaque);
+/**
+ * in_aio_context_home_thread:
+ * @ctx: the aio context
+ *
+ * Return whether we are running in the thread that normally runs @ctx. Note
+ * that acquiring/releasing ctx does not affect the outcome, each AioContext
+ * still only has one home thread that is responsible for running it.
+ */
+static inline bool in_aio_context_home_thread(AioContext *ctx)
+{
+ if (ctx == qemu_get_current_aio_context()) {
+ return true;
+ }
+
+ if (ctx == qemu_get_aio_context()) {
+ return qemu_mutex_iothread_locked();
+ } else {
+ return false;
+ }
+}
+
#endif /* QEMU_AIO_WAIT_H */