mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-12-29 18:50:29 -07:00
AioContext: optimize clearing the EventNotifier
It is pretty rare for aio_notify to actually set the EventNotifier. It can happen with worker threads such as thread-pool.c's, but otherwise it should never be set thanks to the ctx->notify_me optimization. The previous patch, unfortunately, added an unconditional call to event_notifier_test_and_clear; now add a userspace fast path that avoids the call. Note that it is not possible to do the same with event_notifier_set; it would break, as proved (again) by the included formal model. This patch survived over 3000 reboots on aarch64 KVM. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Fam Zheng <famz@redhat.com> Tested-by: Richard W.M. Jones <rjones@redhat.com> Message-id: 1437487673-23740-7-git-send-email-pbonzini@redhat.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
parent
21a03d17f2
commit
05e514b1d4
5 changed files with 194 additions and 4 deletions
|
|
@ -99,7 +99,19 @@ struct AioContext {
|
|||
*/
|
||||
int walking_bh;
|
||||
|
||||
/* Used for aio_notify. */
|
||||
/* Used by aio_notify.
|
||||
*
|
||||
* "notified" is used to avoid expensive event_notifier_test_and_clear
|
||||
* calls. When it is clear, the EventNotifier is clear, or one thread
|
||||
* is going to clear "notified" before processing more events. False
|
||||
* positives are possible, i.e. "notified" could be set even though the
|
||||
* EventNotifier is clear.
|
||||
*
|
||||
* Note that event_notifier_set *cannot* be optimized the same way. For
|
||||
* more information on the problem that would result, see "#ifdef BUG2"
|
||||
* in the docs/aio_notify_accept.promela formal model.
|
||||
*/
|
||||
bool notified;
|
||||
EventNotifier notifier;
|
||||
|
||||
/* Thread pool for performing work and receiving completion callbacks */
|
||||
|
|
@ -173,6 +185,24 @@ QEMUBH *aio_bh_new(AioContext *ctx, QEMUBHFunc *cb, void *opaque);
|
|||
*/
|
||||
void aio_notify(AioContext *ctx);
|
||||
|
||||
/**
|
||||
* aio_notify_accept: Acknowledge receiving an aio_notify.
|
||||
*
|
||||
* aio_notify() uses an EventNotifier in order to wake up a sleeping
|
||||
* aio_poll() or g_main_context_iteration(). Calls to aio_notify() are
|
||||
* usually rare, but the AioContext has to clear the EventNotifier on
|
||||
* every aio_poll() or g_main_context_iteration() in order to avoid
|
||||
* busy waiting. This event_notifier_test_and_clear() cannot be done
|
||||
* using the usual aio_context_set_event_notifier(), because it must
|
||||
* be done before processing all events (file descriptors, bottom halves,
|
||||
* timers).
|
||||
*
|
||||
* aio_notify_accept() is an optimized event_notifier_test_and_clear()
|
||||
* that is specific to an AioContext's notifier; it is used internally
|
||||
* to clear the EventNotifier only if aio_notify() had been called.
|
||||
*/
|
||||
void aio_notify_accept(AioContext *ctx);
|
||||
|
||||
/**
|
||||
* aio_bh_poll: Poll bottom halves for an AioContext.
|
||||
*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue