On Fri, Apr 13, 2012 at 3:18 PM, Paolo Bonzini <pbonz...@redhat.com> wrote: > Il 13/04/2012 03:55, Zhi Yong Wu ha scritto: >> On Thu, Apr 12, 2012 at 8:00 PM, Paolo Bonzini <pbonz...@redhat.com> wrote: >>> From: Zhi Yong Wu <wu...@linux.vnet.ibm.com> >>> >>> Signed-off-by: Zhi Yong Wu <wu...@linux.vnet.ibm.com> >>> [ Iterate until all block devices have processed all requests, >>> add comments. - Paolo ] >>> Signed-off-by: Paolo Bonzini <pbonz...@redhat.com> >>> --- >>> block.c | 21 ++++++++++++++++++++- >>> 1 file changed, 20 insertions(+), 1 deletion(-) >>> >>> diff --git a/block.c b/block.c >>> index 4b96654..33efa95 100644 >>> --- a/block.c >>> +++ b/block.c >>> @@ -863,12 +863,31 @@ void bdrv_close_all(void) >>> * >>> * This function does not flush data to disk, use bdrv_flush_all() for that >>> * after calling this function. >>> + * >>> + * Note that completion of an asynchronous I/O operation can trigger any >>> + * number of other I/O operations on other devices---for example a >>> coroutine >>> + * can be arbitrarily complex and a constant flow of I/O can come until the >>> + * coroutine is complete. Because of this, it is not possible to have a >>> + * function to drain a single device's I/O queue. >>> */ >>> void bdrv_drain_all(void) >>> { >>> BlockDriverState *bs; >>> + bool busy; >>> >>> - qemu_aio_flush(); >>> + do { >>> + busy = qemu_aio_wait(); >> When bdrv_drain_all is invoked, if bs->tracked_requests has some >> pending I/O requests, only qemu_aio_wait is called here, not >> qemu_aio_flush() to restart them in bs->tracked_requests. It will >> cause assert about bs->tracked_requests. > > qemu_aio_flush does not do that. Instead, the code just below does it: Sorry, i hadn't check the code. thanks for pointing out this. In the past, i tested this patch, and found it will assert about bs->tracked_requests. Do you think that only qemu_aio_wait can make sure that bs->tracked_requests is empty here? > >>> + >>> + /* FIXME: We do not have timer support here, so this is effectively >>> + * a busy wait. >>> + */ >>> + QTAILQ_FOREACH(bs, &bdrv_states, list) { >>> + if (!qemu_co_queue_empty(&bs->throttled_reqs)) { >>> + qemu_co_queue_restart_all(&bs->throttled_reqs); >>> + busy = true; >>> + } >>> + } >>> + } while (busy); >>> >>> /* If requests are still pending there is a bug somewhere */ >>> QTAILQ_FOREACH(bs, &bdrv_states, list) { >>> -- >>> 1.7.9.3 >>> >>> >>> >> >> >> > > >
-- Regards, Zhi Yong Wu