On Thu, Jun 16, 2016 at 11:21 AM, Paolo Bonzini <pbonz...@redhat.com> wrote: > > > On 16/06/2016 12:17, Stefan Hajnoczi wrote: >> On Wed, Jun 15, 2016 at 10:57:49AM +0200, Paolo Bonzini wrote: >>> On 14/06/2016 20:17, Stefan Hajnoczi wrote: >>>> +/* There is no matching mirror_resume() because mirror_run() will begin >>>> + * iterating again when the job is resumed. >>>> + */ >>>> +static void mirror_pause(BlockJob *job) >>>> +{ >>>> + MirrorBlockJob *s = container_of(job, MirrorBlockJob, common); >>>> + >>>> + while (s->in_flight > 0) { >>>> + aio_poll(blk_get_aio_context(job->blk), true); >>>> + } >>> >>> This is calling aio_poll from a coroutine, which is ugly -- see Fam's >>> recent introduction of bdrv_co_drain. I think this should call >>> mirror_drain instead. >> >> This is not called from coroutine context, so I couldn't use >> mirror_drain(). >> >> BlockJobDriver->pause() and attached_aio_context() are both not >> coroutine_fn. That's because bdrv_attach_aio_context() is not >> coroutine_fn and can be called from a monitor command or device >> emulation code. > > But mirror_pause is only called from block_job_pause_point, isn't it? > And block_job_pause_point is a coroutine_fn.
You are right. I managed to confuse myself! I'll rework the APIs to make them coroutine_fn as appropriate. Stefan