On Fri, 04/01 11:49, Paolo Bonzini wrote: > > > On 01/04/2016 11:46, Fam Zheng wrote: > > + > > +static void bdrv_co_drain_bh_cb(void *opaque) > > +{ > > + BdrvCoDrainData *data = opaque; > > + Coroutine *co = data->co; > > + > > + bdrv_drain(data->bs); > > + data->done = true; > > + qemu_coroutine_enter(co, NULL); > > +} > > + > > +static void coroutine_fn bdrv_co_drain(BlockDriverState *bs) > > +{ > > + QEMUBH *bh; > > + BdrvCoDrainData data; > > + > > + assert(qemu_in_coroutine()); > > + data = (BdrvCoDrainData) { > > + .co = qemu_coroutine_self(), > > + .bs = bs, > > + .done = false, > > + }; > > + bh = aio_bh_new(bdrv_get_aio_context(bs), bdrv_co_drain_bh_cb, &data), > > + qemu_bh_schedule(bh); > > + > > + do { > > + qemu_coroutine_yield(); > > + } while (!data.done); > > The loop and "done" is not necessary. Also,
I was trying to protect against the bugs similar to the one fixed in e424aff5f30, but you're right we can make this an assertion and the loop is not needed. If a calling coroutine is resumed unexpectedly, we will catch it and fix it. > > > + qemu_bh_delete(bh); > > this can be moved to bdrv_co_drain_bh_cb before bdrv_drain, so that the > bottom half doesn't slow down the event loop until bdrv_drain completes. Good point! Will fix. Thanks, Fam