mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-29 21:12:07 -06:00
AioContext: speed up aio_notify
In many cases, the call to event_notifier_set in aio_notify is unnecessary. In particular, if we are executing aio_dispatch, or if aio_poll is not blocking, we know that we will soon get to the next loop iteration (if necessary); the thread that hosts the AioContext's event loop does not need any nudging. The patch includes a Promela formal model that shows that this really works and does not need any further complication such as generation counts. It needs a memory barrier though. The generation counts are not needed because any change to ctx->dispatching after the memory barrier is okay for aio_notify. If it changes from zero to one, it is the right thing to skip event_notifier_set. If it changes from one to zero, the event_notifier_set is unnecessary but harmless. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
ef508f427b
commit
0ceb849bd3
4 changed files with 164 additions and 2 deletions
19
async.c
19
async.c
|
@ -26,6 +26,7 @@
|
|||
#include "block/aio.h"
|
||||
#include "block/thread-pool.h"
|
||||
#include "qemu/main-loop.h"
|
||||
#include "qemu/atomic.h"
|
||||
|
||||
/***********************************************************/
|
||||
/* bottom halves (can be seen as timers which expire ASAP) */
|
||||
|
@ -247,9 +248,25 @@ ThreadPool *aio_get_thread_pool(AioContext *ctx)
|
|||
return ctx->thread_pool;
|
||||
}
|
||||
|
||||
void aio_set_dispatching(AioContext *ctx, bool dispatching)
|
||||
{
|
||||
ctx->dispatching = dispatching;
|
||||
if (!dispatching) {
|
||||
/* Write ctx->dispatching before reading e.g. bh->scheduled.
|
||||
* Optimization: this is only needed when we're entering the "unsafe"
|
||||
* phase where other threads must call event_notifier_set.
|
||||
*/
|
||||
smp_mb();
|
||||
}
|
||||
}
|
||||
|
||||
void aio_notify(AioContext *ctx)
|
||||
{
|
||||
event_notifier_set(&ctx->notifier);
|
||||
/* Write e.g. bh->scheduled before reading ctx->dispatching. */
|
||||
smp_mb();
|
||||
if (!ctx->dispatching) {
|
||||
event_notifier_set(&ctx->notifier);
|
||||
}
|
||||
}
|
||||
|
||||
static void aio_timerlist_notify(void *opaque)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue