On 5/12/20 4:43 PM, Kevin Wolf wrote: > Coroutine functions that are entered through bdrv_run_co() are already > safe to call from synchronous code in a different AioContext because > bdrv_coroutine_enter() will schedule them in the context of the node. > > However, the coroutine fastpath still requires that we're already in the > right AioContext when called in coroutine context. > > In order to make the behaviour more consistent and to make life a bit > easier for callers, let's check the AioContext and automatically move > the current coroutine around if we're not in the right context yet. > > Signed-off-by: Kevin Wolf <kw...@redhat.com> > --- > block/io.c | 15 ++++++++++++++- > 1 file changed, 14 insertions(+), 1 deletion(-) > > diff --git a/block/io.c b/block/io.c > index c1badaadc9..7808e8bdc0 100644 > --- a/block/io.c > +++ b/block/io.c > @@ -895,8 +895,21 @@ static int bdrv_run_co(BlockDriverState *bs, > CoroutineEntry *entry, > void *opaque, int *ret) > { > if (qemu_in_coroutine()) { > - /* Fast-path if already in coroutine context */ > + Coroutine *self = qemu_coroutine_self(); > + AioContext *bs_ctx = bdrv_get_aio_context(bs); > + AioContext *co_ctx = qemu_coroutine_get_aio_context(self); > + > + if (bs_ctx != co_ctx) { > + /* Move to the iothread of the node */ > + aio_co_schedule(bs_ctx, self); > + qemu_coroutine_yield(); > + } > entry(opaque); > + if (bs_ctx != co_ctx) { > + /* Move back to the original AioContext */ > + aio_co_schedule(bs_ctx, self);
shouldn't it use co_ctx here, as else it's just scheduled again on the one from bs? Looks OK for me besides that. > + qemu_coroutine_yield(); > + } > } else { > Coroutine *co = qemu_coroutine_create(entry, opaque); > *ret = NOT_DONE; >