From: Jeff Cody <jcody@redhat.com>
To: Max Reitz <mreitz@redhat.com>
Cc: qemu-block@nongnu.org, Kevin Wolf <kwolf@redhat.com>,
Fam Zheng <famz@redhat.com>,
qemu-devel@nongnu.org, Stefan Hajnoczi <stefanha@redhat.com>
Subject: Re: [Qemu-devel] [Qemu-block] [PATCH v3 01/16] block: BDS deletion during bdrv_drain_recurse
Date: Mon, 19 Mar 2018 23:10:28 -0400 [thread overview]
Message-ID: <20180320031028.GD2962@localhost.localdomain> (raw)
In-Reply-To: <20180228180507.3964-2-mreitz@redhat.com>
On Wed, Feb 28, 2018 at 07:04:52PM +0100, Max Reitz wrote:
> Draining a BDS child may lead to other children of the same parent being
> detached and/or deleted. We should prepare for the former case (by
> copying the children list before iterating through it) and prevent the
> latter (by bdrv_ref()'ing all nodes if we are in the main loop).
>
> Signed-off-by: Max Reitz <mreitz@redhat.com>
> ---
> block/io.c | 40 ++++++++++++++++++++++++++++++----------
> 1 file changed, 30 insertions(+), 10 deletions(-)
>
> diff --git a/block/io.c b/block/io.c
> index 4d3d1f640a..ead12c4136 100644
> --- a/block/io.c
> +++ b/block/io.c
> @@ -189,31 +189,51 @@ static void bdrv_drain_invoke(BlockDriverState *bs, bool begin, bool recursive)
>
> static bool bdrv_drain_recurse(BlockDriverState *bs)
> {
> - BdrvChild *child, *tmp;
> + BdrvChild *child;
> bool waited;
> + struct BDSToDrain {
> + BlockDriverState *bs;
> + QLIST_ENTRY(BDSToDrain) next;
> + };
> + QLIST_HEAD(, BDSToDrain) bs_list = QLIST_HEAD_INITIALIZER(bs_list);
> + bool in_main_loop =
> + qemu_get_current_aio_context() == qemu_get_aio_context();
>
> /* Wait for drained requests to finish */
> waited = BDRV_POLL_WHILE(bs, atomic_read(&bs->in_flight) > 0);
>
> - QLIST_FOREACH_SAFE(child, &bs->children, next, tmp) {
> - BlockDriverState *bs = child->bs;
> - bool in_main_loop =
> - qemu_get_current_aio_context() == qemu_get_aio_context();
> - assert(bs->refcnt > 0);
> + /* Draining children may result in other children being removed from this
> + * parent and maybe even deleted, so copy the children list first */
> + QLIST_FOREACH(child, &bs->children, next) {
> + struct BDSToDrain *bs2d = g_new0(struct BDSToDrain, 1);
> +
> + bs2d->bs = child->bs;
> if (in_main_loop) {
> /* In case the recursive bdrv_drain_recurse processes a
> * block_job_defer_to_main_loop BH and modifies the graph,
> - * let's hold a reference to bs until we are done.
> + * let's hold a reference to the BDS until we are done.
> *
> * IOThread doesn't have such a BH, and it is not safe to call
> * bdrv_unref without BQL, so skip doing it there.
> */
> - bdrv_ref(bs);
> + bdrv_ref(bs2d->bs);
> }
> - waited |= bdrv_drain_recurse(bs);
> +
> + QLIST_INSERT_HEAD(&bs_list, bs2d, next);
> + }
> +
> + while (!QLIST_EMPTY(&bs_list)) {
> + struct BDSToDrain *bs2d = QLIST_FIRST(&bs_list);
> + QLIST_REMOVE(bs2d, next);
> +
> + assert(bs2d->bs->refcnt > 0);
> +
> + waited |= bdrv_drain_recurse(bs2d->bs);
> if (in_main_loop) {
> - bdrv_unref(bs);
> + bdrv_unref(bs2d->bs);
> }
> +
> + g_free(bs2d);
> }
>
> return waited;
> --
> 2.14.3
>
>
Reviewed-by: Jeff Cody <jcody@redhat.com>
next prev parent reply other threads:[~2018-03-20 3:10 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-02-28 18:04 [Qemu-devel] [PATCH v3 00/16] block/mirror: Add active-sync mirroring Max Reitz
2018-02-28 18:04 ` [Qemu-devel] [PATCH v3 01/16] block: BDS deletion during bdrv_drain_recurse Max Reitz
2018-03-20 3:10 ` Jeff Cody [this message]
2018-02-28 18:04 ` [Qemu-devel] [PATCH v3 02/16] block: BDS deletion in bdrv_do_drained_begin() Max Reitz
2018-03-20 3:16 ` [Qemu-devel] [Qemu-block] " Jeff Cody
2018-02-28 18:04 ` [Qemu-devel] [PATCH v3 03/16] tests: Add bdrv-drain test for node deletion Max Reitz
2018-02-28 18:04 ` [Qemu-devel] [PATCH v3 04/16] block/mirror: Pull out mirror_perform() Max Reitz
2018-03-20 3:30 ` [Qemu-devel] [Qemu-block] " Jeff Cody
2018-02-28 18:04 ` [Qemu-devel] [PATCH v3 05/16] block/mirror: Convert to coroutines Max Reitz
2018-02-28 18:04 ` [Qemu-devel] [PATCH v3 06/16] block/mirror: Use CoQueue to wait on in-flight ops Max Reitz
2018-02-28 18:04 ` [Qemu-devel] [PATCH v3 07/16] block/mirror: Wait for in-flight op conflicts Max Reitz
2018-02-28 18:04 ` [Qemu-devel] [PATCH v3 08/16] block/mirror: Use source as a BdrvChild Max Reitz
2018-02-28 18:05 ` [Qemu-devel] [PATCH v3 09/16] block: Generalize should_update_child() rule Max Reitz
2018-02-28 18:05 ` [Qemu-devel] [PATCH v3 10/16] hbitmap: Add @advance param to hbitmap_iter_next() Max Reitz
2018-02-28 18:05 ` [Qemu-devel] [PATCH v3 11/16] test-hbitmap: Add non-advancing iter_next tests Max Reitz
2018-03-01 7:00 ` Fam Zheng
2018-02-28 18:05 ` [Qemu-devel] [PATCH v3 12/16] block/dirty-bitmap: Add bdrv_dirty_iter_next_area Max Reitz
2018-03-15 19:51 ` John Snow
2018-02-28 18:05 ` [Qemu-devel] [PATCH v3 13/16] block/mirror: Add MirrorBDSOpaque Max Reitz
2018-02-28 18:05 ` [Qemu-devel] [PATCH v3 14/16] block/mirror: Add active mirroring Max Reitz
2018-02-28 18:05 ` [Qemu-devel] [PATCH v3 15/16] block/mirror: Add copy mode QAPI interface Max Reitz
2018-03-20 17:35 ` Eric Blake
2018-03-21 11:25 ` Max Reitz
2018-02-28 18:05 ` [Qemu-devel] [PATCH v3 16/16] iotests: Add test for active mirroring Max Reitz
2018-02-28 18:55 ` [Qemu-devel] [PATCH v3 00/16] block/mirror: Add active-sync mirroring no-reply
2018-03-01 7:08 ` Fam Zheng
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=20180320031028.GD2962@localhost.localdomain \
--to=jcody@redhat.com \
--cc=famz@redhat.com \
--cc=kwolf@redhat.com \
--cc=mreitz@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.