Skip to content

Commit 3c18a92

Browse files
bonzinistefanhaRH
authored andcommitted
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 <[email protected]> Message-Id: <[email protected]> Signed-off-by: Stefan Hajnoczi <[email protected]>
1 parent 636b836 commit 3c18a92

File tree

2 files changed

+32
-19
lines changed

2 files changed

+32
-19
lines changed

include/block/aio-wait.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#define QEMU_AIO_WAIT_H
2727

2828
#include "block/aio.h"
29+
#include "qemu/main-loop.h"
2930

3031
/**
3132
* AioWait:
@@ -124,4 +125,25 @@ void aio_wait_kick(void);
124125
*/
125126
void aio_wait_bh_oneshot(AioContext *ctx, QEMUBHFunc *cb, void *opaque);
126127

128+
/**
129+
* in_aio_context_home_thread:
130+
* @ctx: the aio context
131+
*
132+
* Return whether we are running in the thread that normally runs @ctx. Note
133+
* that acquiring/releasing ctx does not affect the outcome, each AioContext
134+
* still only has one home thread that is responsible for running it.
135+
*/
136+
static inline bool in_aio_context_home_thread(AioContext *ctx)
137+
{
138+
if (ctx == qemu_get_current_aio_context()) {
139+
return true;
140+
}
141+
142+
if (ctx == qemu_get_aio_context()) {
143+
return qemu_mutex_iothread_locked();
144+
} else {
145+
return false;
146+
}
147+
}
148+
127149
#endif /* QEMU_AIO_WAIT_H */

include/block/aio.h

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,16 @@ struct AioContext {
133133
AioHandlerList deleted_aio_handlers;
134134

135135
/* Used to avoid unnecessary event_notifier_set calls in aio_notify;
136-
* accessed with atomic primitives. If this field is 0, everything
137-
* (file descriptors, bottom halves, timers) will be re-evaluated
138-
* before the next blocking poll(), thus the event_notifier_set call
139-
* can be skipped. If it is non-zero, you may need to wake up a
140-
* concurrent aio_poll or the glib main event loop, making
141-
* event_notifier_set necessary.
136+
* only written from the AioContext home thread, or under the BQL in
137+
* the case of the main AioContext. However, it is read from any
138+
* thread so it is still accessed with atomic primitives.
139+
*
140+
* If this field is 0, everything (file descriptors, bottom halves,
141+
* timers) will be re-evaluated before the next blocking poll() or
142+
* io_uring wait; therefore, the event_notifier_set call can be
143+
* skipped. If it is non-zero, you may need to wake up a concurrent
144+
* aio_poll or the glib main event loop, making event_notifier_set
145+
* necessary.
142146
*
143147
* Bit 0 is reserved for GSource usage of the AioContext, and is 1
144148
* between a call to aio_ctx_prepare and the next call to aio_ctx_check.
@@ -681,19 +685,6 @@ void aio_co_enter(AioContext *ctx, struct Coroutine *co);
681685
*/
682686
AioContext *qemu_get_current_aio_context(void);
683687

684-
/**
685-
* in_aio_context_home_thread:
686-
* @ctx: the aio context
687-
*
688-
* Return whether we are running in the thread that normally runs @ctx. Note
689-
* that acquiring/releasing ctx does not affect the outcome, each AioContext
690-
* still only has one home thread that is responsible for running it.
691-
*/
692-
static inline bool in_aio_context_home_thread(AioContext *ctx)
693-
{
694-
return ctx == qemu_get_current_aio_context();
695-
}
696-
697688
/**
698689
* aio_context_setup:
699690
* @ctx: the aio context

0 commit comments

Comments
 (0)