diff options
| author | Paolo Bonzini <pbonzini@redhat.com> | 2017-02-13 14:52:19 +0100 |
|---|---|---|
| committer | Stefan Hajnoczi <stefanha@redhat.com> | 2017-02-21 11:14:07 +0000 |
| commit | 0c330a734b51c177ab8488932ac3b0c4d63a718a (patch) | |
| tree | 1251fc380ca5313495d9a9c541460b3ac2ffb7e0 /util/qemu-coroutine.c | |
| parent | c2b38b277a7882a592f4f2ec955084b2b756daaa (diff) | |
| download | focaccia-qemu-0c330a734b51c177ab8488932ac3b0c4d63a718a.tar.gz focaccia-qemu-0c330a734b51c177ab8488932ac3b0c4d63a718a.zip | |
aio: introduce aio_co_schedule and aio_co_wake
aio_co_wake provides the infrastructure to start a coroutine on a "home" AioContext. It will be used by CoMutex and CoQueue, so that coroutines don't jump from one context to another when they go to sleep on a mutex or waitqueue. However, it can also be used as a more efficient alternative to one-shot bottom halves, and saves the effort of tracking which AioContext a coroutine is running on. aio_co_schedule is the part of aio_co_wake that starts a coroutine on a remove AioContext, but it is also useful to implement e.g. bdrv_set_aio_context callbacks. The implementation of aio_co_schedule is based on a lock-free multiple-producer, single-consumer queue. The multiple producers use cmpxchg to add to a LIFO stack. The consumer (a per-AioContext bottom half) grabs all items added so far, inverts the list to make it FIFO, and goes through it one item at a time until it's empty. The data structure was inspired by OSv, which uses it in the very code we'll "port" to QEMU for the thread-safe CoMutex. Most of the new code is really tests. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Fam Zheng <famz@redhat.com> Message-id: 20170213135235.12274-3-pbonzini@redhat.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'util/qemu-coroutine.c')
| -rw-r--r-- | util/qemu-coroutine.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/util/qemu-coroutine.c b/util/qemu-coroutine.c index a5d2f6c0c3..415600dc30 100644 --- a/util/qemu-coroutine.c +++ b/util/qemu-coroutine.c @@ -19,6 +19,7 @@ #include "qemu/atomic.h" #include "qemu/coroutine.h" #include "qemu/coroutine_int.h" +#include "block/aio.h" enum { POOL_BATCH_SIZE = 64, @@ -114,6 +115,13 @@ void qemu_coroutine_enter(Coroutine *co) } co->caller = self; + co->ctx = qemu_get_current_aio_context(); + + /* Store co->ctx before anything that stores co. Matches + * barrier in aio_co_wake. + */ + smp_wmb(); + ret = qemu_coroutine_switch(self, co, COROUTINE_ENTER); qemu_co_queue_run_restart(co); |