From: Stefan Hajnoczi <stefanha@redhat.com>
To: qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
Stefan Hajnoczi <stefanha@redhat.com>
Subject: [Qemu-devel] [PULL 05/42] block: add bdrv_set_aio_context()
Date: Fri, 6 Jun 2014 18:13:26 +0200 [thread overview]
Message-ID: <1402071243-16702-6-git-send-email-stefanha@redhat.com> (raw)
In-Reply-To: <1402071243-16702-1-git-send-email-stefanha@redhat.com>
Up until now all BlockDriverState instances have used the QEMU main loop
for fd handlers, timers, and BHs. This is not scalable on SMP guests
and hosts so we need to move to a model with multiple event loops on
different host CPUs.
bdrv_set_aio_context() assigns the AioContext event loop to use for a
particular BlockDriverState. It first detaches the entire
BlockDriverState graph from the current AioContext and then attaches to
the new AioContext.
This function will be used by virtio-blk data-plane to assign a
BlockDriverState to its IOThread AioContext. Make
bdrv_aio_set_context() public since data-plane should not include
block_int.h.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
block.c | 57 +++++++++++++++++++++++++++++++++++++++++++++--
include/block/block.h | 11 +++++++++
include/block/block_int.h | 36 ++++++++++++++++++++++++++++++
3 files changed, 102 insertions(+), 2 deletions(-)
diff --git a/block.c b/block.c
index 87da79f..1fd3815 100644
--- a/block.c
+++ b/block.c
@@ -363,6 +363,7 @@ BlockDriverState *bdrv_new(const char *device_name, Error **errp)
qemu_co_queue_init(&bs->throttled_reqs[0]);
qemu_co_queue_init(&bs->throttled_reqs[1]);
bs->refcnt = 1;
+ bs->aio_context = qemu_get_aio_context();
return bs;
}
@@ -5661,8 +5662,60 @@ out:
AioContext *bdrv_get_aio_context(BlockDriverState *bs)
{
- /* Currently BlockDriverState always uses the main loop AioContext */
- return qemu_get_aio_context();
+ return bs->aio_context;
+}
+
+void bdrv_detach_aio_context(BlockDriverState *bs)
+{
+ if (!bs->drv) {
+ return;
+ }
+
+ if (bs->drv->bdrv_detach_aio_context) {
+ bs->drv->bdrv_detach_aio_context(bs);
+ }
+ if (bs->file) {
+ bdrv_detach_aio_context(bs->file);
+ }
+ if (bs->backing_hd) {
+ bdrv_detach_aio_context(bs->backing_hd);
+ }
+
+ bs->aio_context = NULL;
+}
+
+void bdrv_attach_aio_context(BlockDriverState *bs,
+ AioContext *new_context)
+{
+ if (!bs->drv) {
+ return;
+ }
+
+ bs->aio_context = new_context;
+
+ if (bs->backing_hd) {
+ bdrv_attach_aio_context(bs->backing_hd, new_context);
+ }
+ if (bs->file) {
+ bdrv_attach_aio_context(bs->file, new_context);
+ }
+ if (bs->drv->bdrv_attach_aio_context) {
+ bs->drv->bdrv_attach_aio_context(bs, new_context);
+ }
+}
+
+void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context)
+{
+ bdrv_drain_all(); /* ensure there are no in-flight requests */
+
+ bdrv_detach_aio_context(bs);
+
+ /* This function executes in the old AioContext so acquire the new one in
+ * case it runs in a different thread.
+ */
+ aio_context_acquire(new_context);
+ bdrv_attach_aio_context(bs, new_context);
+ aio_context_release(new_context);
}
void bdrv_add_before_write_notifier(BlockDriverState *bs,
diff --git a/include/block/block.h b/include/block/block.h
index faee3aa..292754f 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -574,4 +574,15 @@ int bdrv_debug_remove_breakpoint(BlockDriverState *bs, const char *tag);
int bdrv_debug_resume(BlockDriverState *bs, const char *tag);
bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag);
+/**
+ * bdrv_set_aio_context:
+ *
+ * Changes the #AioContext used for fd handlers, timers, and BHs by this
+ * BlockDriverState and all its children.
+ *
+ * This function must be called from the old #AioContext or with a lock held so
+ * the old #AioContext is not executing.
+ */
+void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context);
+
#endif
diff --git a/include/block/block_int.h b/include/block/block_int.h
index f2e753f..93ec86f 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -247,6 +247,19 @@ struct BlockDriver {
*/
int (*bdrv_has_zero_init)(BlockDriverState *bs);
+ /* Remove fd handlers, timers, and other event loop callbacks so the event
+ * loop is no longer in use. Called with no in-flight requests and in
+ * depth-first traversal order with parents before child nodes.
+ */
+ void (*bdrv_detach_aio_context)(BlockDriverState *bs);
+
+ /* Add fd handlers, timers, and other event loop callbacks so I/O requests
+ * can be processed again. Called with no in-flight requests and in
+ * depth-first traversal order with child nodes before parent nodes.
+ */
+ void (*bdrv_attach_aio_context)(BlockDriverState *bs,
+ AioContext *new_context);
+
QLIST_ENTRY(BlockDriver) list;
};
@@ -297,6 +310,8 @@ struct BlockDriverState {
const BlockDevOps *dev_ops;
void *dev_opaque;
+ AioContext *aio_context; /* event loop used for fd handlers, timers, etc */
+
char filename[1024];
char backing_file[1024]; /* if non zero, the image is a diff of
this file image */
@@ -396,6 +411,27 @@ void bdrv_add_before_write_notifier(BlockDriverState *bs,
*/
AioContext *bdrv_get_aio_context(BlockDriverState *bs);
+/**
+ * bdrv_detach_aio_context:
+ *
+ * May be called from .bdrv_detach_aio_context() to detach children from the
+ * current #AioContext. This is only needed by block drivers that manage their
+ * own children. Both ->file and ->backing_hd are automatically handled and
+ * block drivers should not call this function on them explicitly.
+ */
+void bdrv_detach_aio_context(BlockDriverState *bs);
+
+/**
+ * bdrv_attach_aio_context:
+ *
+ * May be called from .bdrv_attach_aio_context() to attach children to the new
+ * #AioContext. This is only needed by block drivers that manage their own
+ * children. Both ->file and ->backing_hd are automatically handled and block
+ * drivers should not call this function on them explicitly.
+ */
+void bdrv_attach_aio_context(BlockDriverState *bs,
+ AioContext *new_context);
+
#ifdef _WIN32
int is_windows_drive(const char *filename);
#endif
--
1.9.3
next prev parent reply other threads:[~2014-06-06 16:14 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-06-06 16:13 [Qemu-devel] [PULL 00/42] Block patches Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 01/42] aio: fix qemu_bh_schedule() bh->ctx race condition Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 02/42] block: use BlockDriverState AioContext Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 03/42] block: acquire AioContext in bdrv_*_all() Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 04/42] block: acquire AioContext in bdrv_drain_all() Stefan Hajnoczi
2014-06-06 16:13 ` Stefan Hajnoczi [this message]
2014-06-06 16:13 ` [Qemu-devel] [PULL 06/42] blkdebug: use BlockDriverState's AioContext Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 07/42] blkverify: implement .bdrv_detach/attach_aio_context() Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 08/42] curl: " Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 09/42] gluster: use BlockDriverState's AioContext Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 10/42] iscsi: implement .bdrv_detach/attach_aio_context() Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 11/42] nbd: " Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 12/42] nfs: " Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 13/42] qed: use BlockDriverState's AioContext Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 14/42] quorum: implement .bdrv_detach/attach_aio_context() Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 15/42] block/raw-posix: " Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 16/42] block/linux-aio: fix memory and fd leak Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 17/42] block/raw-win32: create one QEMUWin32AIOState per BDRVRawState Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 18/42] block/raw-win32: implement .bdrv_detach/attach_aio_context() Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 19/42] rbd: use BlockDriverState's AioContext Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 20/42] sheepdog: implement .bdrv_detach/attach_aio_context() Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 21/42] ssh: use BlockDriverState's AioContext Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 22/42] vmdk: implement .bdrv_detach/attach_aio_context() Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 23/42] dataplane: use the QEMU block layer for I/O Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 24/42] dataplane: delete IOQueue since it is no longer used Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 25/42] dataplane: implement async flush Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 26/42] raw-posix: drop raw_get_aio_fd() since it is no longer used Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 27/42] block: Move declaration of bdrv_get_aio_context to block.h Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 28/42] virtio-blk: Allow config-wce in dataplane Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 29/42] virtio-blk: Factor out virtio_blk_handle_scsi_req from virtio_blk_handle_scsi Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 30/42] dataplane: Support VIRTIO_BLK_T_SCSI_CMD Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 31/42] throttle: add throttle_detach/attach_aio_context() Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 32/42] throttle: add detach/attach test case Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 33/42] blockdev: acquire AioContext in block_set_io_throttle Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 34/42] block: fix wrong order in live block migration setup Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 35/42] qemu-img: Document check exit codes Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 36/42] rbd: Fix leaks in rbd_start_aio() error path Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 37/42] sheepdog: fix vdi object update after live snapshot Stefan Hajnoczi
2014-06-06 16:13 ` [Qemu-devel] [PULL 38/42] sheepdog: reload only header in a case of " Stefan Hajnoczi
2014-06-06 16:14 ` [Qemu-devel] [PULL 39/42] qapi: Extract qapi/common.json definitions Stefan Hajnoczi
2014-06-06 16:14 ` [Qemu-devel] [PULL 40/42] qapi: create two block related json modules Stefan Hajnoczi
2014-06-06 16:14 ` [Qemu-devel] [PULL 41/42] qapi: Extract qapi/block-core.json definitions Stefan Hajnoczi
2014-06-06 16:14 ` [Qemu-devel] [PULL 42/42] qapi: Extract qapi/block.json definitions Stefan Hajnoczi
2014-06-09 12:04 ` [Qemu-devel] [PULL 00/42] Block patches Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1402071243-16702-6-git-send-email-stefanha@redhat.com \
--to=stefanha@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).