qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 02/20] blockjob: introduce .drain callback for j


From: Paolo Bonzini
Subject: Re: [Qemu-devel] [PATCH 02/20] blockjob: introduce .drain callback for jobs
Date: Sat, 3 Dec 2016 04:12:30 -0500 (EST)


----- Original Message -----
> From: "Vladimir Sementsov-Ogievskiy" <address@hidden>
> To: "Paolo Bonzini" <address@hidden>, address@hidden
> Cc: address@hidden, address@hidden, address@hidden
> Sent: Friday, December 2, 2016 3:01:30 PM
> Subject: Re: [Qemu-devel] [PATCH 02/20] blockjob: introduce .drain callback 
> for jobs
> 
> 27.10.2016 13:48, Paolo Bonzini wrote:
> > This is required to decouple block jobs from running in an
> > AioContext.  With multiqueue block devices, a BlockDriverState
> > does not really belong to a single AioContext.
> >
> > The solution is to first wait until all I/O operations are
> > complete; then loop in the main thread for the block job to
> > complete entirely.
>
> Looks like I have a problem with this. block_job_drain enters the job
> only if job.busy = false. But what if job yielded with busy = true?
> 
> My case is the following: in the job I call co_aio_sleep_ns() for some
> time without setting job.busy to false, and it looks like timer doesn't
> work while we are in "while() { block_job_drain() }" loop. If I just set
> "job.busy = false" and "job.busy = true" around co_aio_sleep_ns() all
> start to work.
> 
> I don't want set job.busy to false, because actually job is working -
> several additional coroutines do their work, only the main one (job.co)
> do nothing. I can remove timer, and make other coroutines wake up the
> main one when it needed, and, anyway it looks like better way..
> 
> But the question is: is it ok, that we can't use sleep timer in the job,
> without setting busy = true? Is it right that only io can wake up block
> job coroutine, if it yielded without setting busy=false?

That's more or less correct.  See for example mirror.c.  Whenever it yields
with busy=false, mirror_write_complete will wake the coroutine.

Note that it's also okay to use co_aio_sleep_ns if I/O and _also_ wake the
coroutine on I/O.  Reentering a coroutine automatically interrupts the sleep.

Paolo

> > +    while (!job->deferred_to_main_loop && !job->completed) {
> > +        block_job_drain(job);
> > +    }
> >       while (!job->completed) {
> > -        aio_poll(block_job_get_aio_context(job), true);
> > +        aio_poll(qemu_get_aio_context(), true);
> >       }
> >       ret = (job->cancelled && job->ret == 0) ? -ECANCELED : job->ret;
> >       block_job_unref(job);
> >
> 
> 
> --
> Best regards,
> Vladimir
> 
> 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]