On Fri, Jan 13, 2017 at 02:17:16PM +0100, Paolo Bonzini wrote: > +static void co_schedule_bh_cb(void *opaque) > +{ > + AioContext *ctx = opaque; > + QSLIST_HEAD(, Coroutine) straight, reversed; > + > + QSLIST_MOVE_ATOMIC(&reversed, &ctx->scheduled_coroutines); > + QSLIST_INIT(&straight); > + > + while (!QSLIST_EMPTY(&reversed)) { > + Coroutine *co = QSLIST_FIRST(&reversed); > + QSLIST_REMOVE_HEAD(&reversed, co_scheduled_next); > + QSLIST_INSERT_HEAD(&straight, co, co_scheduled_next); > + } > + > + while (!QSLIST_EMPTY(&straight)) { > + Coroutine *co = QSLIST_FIRST(&straight); > + QSLIST_REMOVE_HEAD(&straight, co_scheduled_next); > + trace_aio_co_schedule_bh_cb(ctx, co); > + qemu_coroutine_enter(co); > + } > +} ctx->scheduled_coroutines is a specialized CoQueue. Was there no way to modify and then use CoQueue instead of open coding it? > +void aio_co_wake(struct Coroutine *co) > +{ > + AioContext *ctx; > + > + /* Read coroutine before co->ctx. Matches smp_wmb in > + * qemu_coroutine_enter. > + */ > + smp_read_barrier_depends(); > + ctx = atomic_read(&co->ctx); > + > + if (ctx != qemu_get_current_aio_context()) { > + aio_co_schedule(ctx, co); > + return; > + } > + > + if (qemu_in_coroutine()) { > + Coroutine *self = qemu_coroutine_self(); > + assert(self != co); > + QSIMPLEQ_INSERT_TAIL(&self->co_queue_wakeup, co, co_queue_next); > + } else { > + aio_context_acquire(ctx); > + qemu_coroutine_enter(co); > + aio_context_release(ctx); Why is it necessary to acquire AioContext here? We're already in ctx.