[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 10/24] block: Propagate AioContext change to parents
From: |
Kevin Wolf |
Subject: |
[Qemu-devel] [PULL 10/24] block: Propagate AioContext change to parents |
Date: |
Mon, 20 May 2019 18:14:39 +0200 |
All block nodes and users in any connected component of the block graph
must be in the same AioContext, so changing the AioContext of one node
must not only change all of its children, but all of its parents (and
in turn their children etc.) as well.
Signed-off-by: Kevin Wolf <address@hidden>
---
include/block/block.h | 2 ++
include/block/block_int.h | 1 +
block.c | 48 ++++++++++++++++++++++++++++++++++-----
3 files changed, 45 insertions(+), 6 deletions(-)
diff --git a/include/block/block.h b/include/block/block.h
index fc0239a887..9b083e2bca 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -586,6 +586,8 @@ void bdrv_coroutine_enter(BlockDriverState *bs, Coroutine
*co);
* This function must be called with iothread lock held.
*/
void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context);
+void bdrv_set_aio_context_ignore(BlockDriverState *bs,
+ AioContext *new_context, GSList **ignore);
int bdrv_try_set_aio_context(BlockDriverState *bs, AioContext *ctx,
Error **errp);
int bdrv_child_try_set_aio_context(BlockDriverState *bs, AioContext *ctx,
diff --git a/include/block/block_int.h b/include/block/block_int.h
index aa2c638b02..1eebc7c8f3 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -694,6 +694,7 @@ struct BdrvChildRole {
bool (*can_set_aio_ctx)(BdrvChild *child, AioContext *ctx,
GSList **ignore, Error **errp);
+ void (*set_aio_ctx)(BdrvChild *child, AioContext *ctx, GSList **ignore);
};
extern const BdrvChildRole child_file;
diff --git a/block.c b/block.c
index 0ace673925..1e5230f98e 100644
--- a/block.c
+++ b/block.c
@@ -943,6 +943,13 @@ static bool bdrv_child_cb_can_set_aio_ctx(BdrvChild
*child, AioContext *ctx,
return bdrv_can_set_aio_context(bs, ctx, ignore, errp);
}
+static void bdrv_child_cb_set_aio_ctx(BdrvChild *child, AioContext *ctx,
+ GSList **ignore)
+{
+ BlockDriverState *bs = child->opaque;
+ return bdrv_set_aio_context_ignore(bs, ctx, ignore);
+}
+
/*
* Returns the options and flags that a temporary snapshot should get, based on
* the originally requested flags (the originally requested image will have
@@ -1011,6 +1018,7 @@ const BdrvChildRole child_file = {
.detach = bdrv_child_cb_detach,
.inactivate = bdrv_child_cb_inactivate,
.can_set_aio_ctx = bdrv_child_cb_can_set_aio_ctx,
+ .set_aio_ctx = bdrv_child_cb_set_aio_ctx,
};
/*
@@ -1038,6 +1046,7 @@ const BdrvChildRole child_format = {
.detach = bdrv_child_cb_detach,
.inactivate = bdrv_child_cb_inactivate,
.can_set_aio_ctx = bdrv_child_cb_can_set_aio_ctx,
+ .set_aio_ctx = bdrv_child_cb_set_aio_ctx,
};
static void bdrv_backing_attach(BdrvChild *c)
@@ -1162,6 +1171,7 @@ const BdrvChildRole child_backing = {
.inactivate = bdrv_child_cb_inactivate,
.update_filename = bdrv_backing_update_filename,
.can_set_aio_ctx = bdrv_child_cb_can_set_aio_ctx,
+ .set_aio_ctx = bdrv_child_cb_set_aio_ctx,
};
static int bdrv_open_flags(BlockDriverState *bs, int flags)
@@ -5731,10 +5741,10 @@ static void bdrv_attach_aio_context(BlockDriverState
*bs,
bs->walking_aio_notifiers = false;
}
-/* The caller must own the AioContext lock for the old AioContext of bs, but it
- * must not own the AioContext lock for new_context (unless new_context is
- * the same as the current context of bs). */
-void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context)
+/* @ignore will accumulate all visited BdrvChild object. The caller is
+ * responsible for freeing the list afterwards. */
+void bdrv_set_aio_context_ignore(BlockDriverState *bs,
+ AioContext *new_context, GSList **ignore)
{
BdrvChild *child;
@@ -5745,7 +5755,20 @@ void bdrv_set_aio_context(BlockDriverState *bs,
AioContext *new_context)
bdrv_drained_begin(bs);
QLIST_FOREACH(child, &bs->children, next) {
- bdrv_set_aio_context(child->bs, new_context);
+ if (g_slist_find(*ignore, child)) {
+ continue;
+ }
+ *ignore = g_slist_prepend(*ignore, child);
+ bdrv_set_aio_context_ignore(child->bs, new_context, ignore);
+ }
+ QLIST_FOREACH(child, &bs->parents, next_parent) {
+ if (g_slist_find(*ignore, child)) {
+ continue;
+ }
+ if (child->role->set_aio_ctx) {
+ *ignore = g_slist_prepend(*ignore, child);
+ child->role->set_aio_ctx(child, new_context, ignore);
+ }
}
bdrv_detach_aio_context(bs);
@@ -5759,6 +5782,16 @@ void bdrv_set_aio_context(BlockDriverState *bs,
AioContext *new_context)
aio_context_release(new_context);
}
+/* The caller must own the AioContext lock for the old AioContext of bs, but it
+ * must not own the AioContext lock for new_context (unless new_context is
+ * the same as the current context of bs). */
+void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context)
+{
+ GSList *ignore_list = NULL;
+ bdrv_set_aio_context_ignore(bs, new_context, &ignore_list);
+ g_slist_free(ignore_list);
+}
+
static bool bdrv_parent_can_set_aio_context(BdrvChild *c, AioContext *ctx,
GSList **ignore, Error **errp)
{
@@ -5831,7 +5864,10 @@ int bdrv_child_try_set_aio_context(BlockDriverState *bs,
AioContext *ctx,
return -EPERM;
}
- bdrv_set_aio_context(bs, ctx);
+ ignore = ignore_child ? g_slist_prepend(NULL, ignore_child) : NULL;
+ bdrv_set_aio_context_ignore(bs, ctx, &ignore);
+ g_slist_free(ignore);
+
return 0;
}
--
2.20.1
- [Qemu-devel] [PULL 01/24] block/file-posix: Truncate in xfs_write_zeroes(), (continued)
- [Qemu-devel] [PULL 01/24] block/file-posix: Truncate in xfs_write_zeroes(), Kevin Wolf, 2019/05/20
- [Qemu-devel] [PULL 09/24] block: Move recursion to bdrv_set_aio_context(), Kevin Wolf, 2019/05/20
- [Qemu-devel] [PULL 05/24] iotest: fix 169: do not run qmp_cont in RUN_STATE_FINISH_MIGRATE, Kevin Wolf, 2019/05/20
- [Qemu-devel] [PULL 03/24] block: Use BDRV_REQUEST_MAX_BYTES instead of BDRV_REQUEST_MAX_SECTORS, Kevin Wolf, 2019/05/20
- [Qemu-devel] [PULL 07/24] block: Add bdrv_try_set_aio_context(), Kevin Wolf, 2019/05/20
- [Qemu-devel] [PULL 04/24] qmp: forbid qmp_cont in RUN_STATE_FINISH_MIGRATE, Kevin Wolf, 2019/05/20
- [Qemu-devel] [PULL 12/24] block: Implement .(can_)set_aio_ctx for BlockBackend, Kevin Wolf, 2019/05/20
- [Qemu-devel] [PULL 11/24] test-block-iothread: Test AioContext propagation through the tree, Kevin Wolf, 2019/05/20
- [Qemu-devel] [PULL 13/24] block: Add blk_set_allow_aio_context_change(), Kevin Wolf, 2019/05/20
- [Qemu-devel] [PULL 02/24] qcow2: Define and use QCOW2_COMPRESSED_SECTOR_SIZE, Kevin Wolf, 2019/05/20
- [Qemu-devel] [PULL 10/24] block: Propagate AioContext change to parents,
Kevin Wolf <=
- [Qemu-devel] [PULL 08/24] block: Make bdrv_attach/detach_aio_context() static, Kevin Wolf, 2019/05/20
- [Qemu-devel] [PULL 16/24] test-block-iothread: Test AioContext propagation for block jobs, Kevin Wolf, 2019/05/20
- [Qemu-devel] [PULL 15/24] blockjob: Remove AioContext notifiers, Kevin Wolf, 2019/05/20
- [Qemu-devel] [PULL 14/24] blockjob: Propagate AioContext change to all job nodes, Kevin Wolf, 2019/05/20
- [Qemu-devel] [PULL 17/24] block/file-posix: Unaligned O_DIRECT block-status, Kevin Wolf, 2019/05/20
- [Qemu-devel] [PULL 21/24] block: Improve "Block node is read-only" message, Kevin Wolf, 2019/05/20
- [Qemu-devel] [PULL 20/24] qemu-img.texi: Describe human-readable info output, Kevin Wolf, 2019/05/20
- [Qemu-devel] [PULL 23/24] iotests.py: Fix VM.run_job, Kevin Wolf, 2019/05/20
- [Qemu-devel] [PULL 22/24] iotests.py: Let assert_qmp() accept an array, Kevin Wolf, 2019/05/20
- [Qemu-devel] [PULL 19/24] qemu-img.texi: Be specific about JSON object types, Kevin Wolf, 2019/05/20