Am 11.10.2016 um 11:54 hat Paolo Bonzini geschrieben: > On 11/10/2016 11:39, Kevin Wolf wrote: > > Am 10.10.2016 um 18:41 hat Paolo Bonzini geschrieben: > >> On 10/10/2016 17:37, Kevin Wolf wrote: > >>>> + while ((job = block_job_next(job))) { > >>>> + AioContext *aio_context = blk_get_aio_context(job->blk); > >>>> + > >>>> + aio_context_acquire(aio_context); > >>>> + block_job_pause(job); > >>>> + aio_context_release(aio_context); > >>>> + } > >>>> + > >>>> bdrv_drain_all(); > >>> > >>> We already have a bdrv_drain_all() here, which does the same thing (and > >>> more) internally, except that it resumes all jobs before it returns. > >>> Maybe what we should do is split bdrv_drain_all() in a begin/end pair, > >>> too. > >> > >> Hey, haven't I just suggested the same? :) I swear I hadn't read this > >> before. > >> > >>> The other point I'm wondering now is whether bdrv_drain_all() should > >>> have the aio_disable/enable_external() pair that bdrv_drain() has. > >> > >> bdrv_drain_all need not have it, but its start/end replacement should. > > > > Doesn't need it because it holds the AioContext lock? > > No, because as soon as bdrv_drain_all exits, external file descriptors > can be triggered again so I don't think the aio_disable/enable_external > actually provides any protection.
Right, what I was thinking of was more like new requests coming in while bdrv_drain_all() is still running. If that happened, the result after bdrv_drain_all() wouldn't be different, but if external file descriptors are still active and the guest keeps sending requests, it could take forever until it returns. But that part is addressed by the AioContext lock, I think. > bdrv_drain_all should really only be used in cases where you already > have some kind of "hold" on external file descriptors, like bdrv_close > uses bdrv_drain(): > > bdrv_drained_begin(bs); /* complete I/O */ > bdrv_flush(bs); > bdrv_drain(bs); /* in case flush left pending I/O */ > > That said, because the simplest implementation of bdrv_drain_all() does > > bdrv_drained_all_start(); > bdrv_drained_all_end(); > > just like bdrv_drain() does it, it's not a very interesting point. > bdrv_drain_all will probably disable/enable external file descriptors, > it just doesn't need that. Yes, of course. Kevin