From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41231) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UnQco-0001U6-OK for qemu-devel@nongnu.org; Fri, 14 Jun 2013 05:49:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UnQcj-0000cz-NU for qemu-devel@nongnu.org; Fri, 14 Jun 2013 05:48:54 -0400 Received: from mx1.redhat.com ([209.132.183.28]:14263) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UnQcj-0000cd-CW for qemu-devel@nongnu.org; Fri, 14 Jun 2013 05:48:49 -0400 From: Stefan Hajnoczi Date: Fri, 14 Jun 2013 11:48:23 +0200 Message-Id: <1371203313-26490-4-git-send-email-stefanha@redhat.com> In-Reply-To: <1371203313-26490-1-git-send-email-stefanha@redhat.com> References: <1371203313-26490-1-git-send-email-stefanha@redhat.com> Subject: [Qemu-devel] [RFC 03/13] block: add BlockDevOps->drain_threads_cb() List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Kevin Wolf , Paolo Bonzini , Anthony Liguori , Ping Fan Liu , Stefan Hajnoczi There are times when the QEMU main loop wishes to drain I/O requests. Up until now bdrv_drain_all() meant that no new guest I/O will be processed until the next event loop iteration. This is no longer true with dataplane since it runs outside the QEMU global mutex. The BlockDevOps->drain_threads_cb() interface allows the device model to drain and stop threads. Once draining completes, the QEMU main loop can be sure that no further I/O will take place until next main loop iteration. Signed-off-by: Stefan Hajnoczi --- block.c | 6 ++++++ include/block/block.h | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/block.c b/block.c index 1c9df27..a3323b2 100644 --- a/block.c +++ b/block.c @@ -1430,6 +1430,12 @@ void bdrv_drain_all(void) BlockDriverState *bs; bool busy; + QTAILQ_FOREACH(bs, &bdrv_states, list) { + if (bs->dev_ops && bs->dev_ops->drain_threads_cb) { + bs->dev_ops->drain_threads_cb(bs->dev_opaque); + } + } + do { busy = qemu_aio_wait(); diff --git a/include/block/block.h b/include/block/block.h index 2307f67..85147bb 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -60,6 +60,15 @@ typedef struct BlockDevOps { * Runs when the size changed (e.g. monitor command block_resize) */ void (*resize_cb)(void *opaque); + /* + * Notifies the device model to drain any emulation threads + * + * Upon return, there must be no new or pending requests outside the QEMU + * main loop. The device model may restart emulation threads after this + * main loop iteration, for example in a hardware register handler + * function. + */ + void (*drain_threads_cb)(void *opaque); } BlockDevOps; #define BDRV_O_RDWR 0x0002 -- 1.8.1.4