From nobody Tue Nov 4 15:14:13 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1530640462851501.4264993518; Tue, 3 Jul 2018 10:54:22 -0700 (PDT) Received: from localhost ([::1]:41983 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1faPVO-0007QW-4S for importer@patchew.org; Tue, 03 Jul 2018 13:54:22 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37840) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1faPS9-00056H-Jy for qemu-devel@nongnu.org; Tue, 03 Jul 2018 13:51:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1faPS8-00034u-HL for qemu-devel@nongnu.org; Tue, 03 Jul 2018 13:51:01 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:41170 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1faPS2-00031I-PO; Tue, 03 Jul 2018 13:50:54 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 45ABEDFC4; Tue, 3 Jul 2018 17:50:54 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-148.ams2.redhat.com [10.36.117.148]) by smtp.corp.redhat.com (Postfix) with ESMTP id 737A42026D76; Tue, 3 Jul 2018 17:50:53 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Tue, 3 Jul 2018 19:50:48 +0200 Message-Id: <20180703175049.27669-2-kwolf@redhat.com> In-Reply-To: <20180703175049.27669-1-kwolf@redhat.com> References: <20180703175049.27669-1-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Tue, 03 Jul 2018 17:50:54 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Tue, 03 Jul 2018 17:50:54 +0000 (UTC) for IP:'10.11.54.4' DOMAIN:'int-mx04.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'kwolf@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH 1/2] block: Poll after drain on attaching a node X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org, mreitz@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Commit dcf94a23b1 ('block: Don't poll in parent drain callbacks') removed polling in bdrv_child_cb_drained_begin() on the grounds that the original bdrv_drain() already will poll and BdrvChildRole.drained_begin calls must not cause graph changes (and therefore must not call aio_poll() or the recursion through the graph will break. This reasoning is correct for calls through bdrv_do_drained_begin(). However, BdrvChildRole.drained_begin is also called when a node that is already in a drained section (i.e. bdrv_do_drained_begin() has already returned and therefore can't poll any more) is attached to a new parent. In this case, we must explicitly poll to have all requests completed before the drained new child can be attached to the parent. In bdrv_replace_child_noperm(), we know that we're not inside the recursion of bdrv_do_drained_begin() because graph changes are not allowed there, and bdrv_replace_child_noperm() is a graph change. The call of BdrvChildRole.drained_begin() must therefore be followed by a BDRV_POLL_WHILE() that waits for the completion of requests. Reported-by: Max Reitz Signed-off-by: Kevin Wolf --- include/block/block.h | 8 ++++++++ include/block/block_int.h | 3 +++ block.c | 2 +- block/io.c | 26 ++++++++++++++++++++------ 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/include/block/block.h b/include/block/block.h index bc76b1e59f..706ef009ad 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -569,6 +569,14 @@ void bdrv_parent_drained_begin(BlockDriverState *bs, B= drvChild *ignore, bool ignore_bds_parents); =20 /** + * bdrv_parent_drained_begin_single: + * + * Begin a quiesced section for the parent of @c. If @poll is true, wait f= or + * any pending activity to cease. + */ +void bdrv_parent_drained_begin_single(BdrvChild *c, bool poll); + +/** * bdrv_parent_drained_end: * * End a quiesced section of all users of @bs. This is part of diff --git a/include/block/block_int.h b/include/block/block_int.h index af71b414be..81cd3db7a9 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -606,6 +606,9 @@ struct BdrvChildRole { * requests after returning from .drained_begin() until .drained_end()= is * called. * + * These functions must not change the graph (and therefore also must = not + * call aio_poll(), which could change the graph indirectly). + * * Note that this can be nested. If drained_begin() was called twice, = new * I/O is allowed only after drained_end() was called twice, too. */ diff --git a/block.c b/block.c index 961ec97d26..fb1462fbf2 100644 --- a/block.c +++ b/block.c @@ -2060,7 +2060,7 @@ static void bdrv_replace_child_noperm(BdrvChild *chil= d, } assert(num >=3D 0); for (i =3D 0; i < num; i++) { - child->role->drained_begin(child); + bdrv_parent_drained_begin_single(child, true); } } =20 diff --git a/block/io.c b/block/io.c index 1a2272fad3..038449f81f 100644 --- a/block/io.c +++ b/block/io.c @@ -52,9 +52,7 @@ void bdrv_parent_drained_begin(BlockDriverState *bs, Bdrv= Child *ignore, if (c =3D=3D ignore || (ignore_bds_parents && c->role->parent_is_b= ds)) { continue; } - if (c->role->drained_begin) { - c->role->drained_begin(c); - } + bdrv_parent_drained_begin_single(c, false); } } =20 @@ -73,6 +71,14 @@ void bdrv_parent_drained_end(BlockDriverState *bs, BdrvC= hild *ignore, } } =20 +static bool bdrv_parent_drained_poll_single(BdrvChild *c) +{ + if (c->role->drained_poll) { + return c->role->drained_poll(c); + } + return false; +} + static bool bdrv_parent_drained_poll(BlockDriverState *bs, BdrvChild *igno= re, bool ignore_bds_parents) { @@ -83,14 +89,22 @@ static bool bdrv_parent_drained_poll(BlockDriverState *= bs, BdrvChild *ignore, if (c =3D=3D ignore || (ignore_bds_parents && c->role->parent_is_b= ds)) { continue; } - if (c->role->drained_poll) { - busy |=3D c->role->drained_poll(c); - } + busy |=3D bdrv_parent_drained_poll_single(c); } =20 return busy; } =20 +void bdrv_parent_drained_begin_single(BdrvChild *c, bool poll) +{ + if (c->role->drained_begin) { + c->role->drained_begin(c); + } + if (poll) { + BDRV_POLL_WHILE(c->bs, bdrv_parent_drained_poll_single(c)); + } +} + static void bdrv_merge_limits(BlockLimits *dst, const BlockLimits *src) { dst->opt_transfer =3D MAX(dst->opt_transfer, src->opt_transfer); --=20 2.13.6 From nobody Tue Nov 4 15:14:13 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1530640380932830.3572558077626; Tue, 3 Jul 2018 10:53:00 -0700 (PDT) Received: from localhost ([::1]:41981 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1faPU4-0006EY-7A for importer@patchew.org; Tue, 03 Jul 2018 13:53:00 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37831) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1faPS9-00055w-5y for qemu-devel@nongnu.org; Tue, 03 Jul 2018 13:51:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1faPS8-00034L-9z for qemu-devel@nongnu.org; Tue, 03 Jul 2018 13:51:01 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:41172 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1faPS3-00031h-Vu; Tue, 03 Jul 2018 13:50:56 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 82B39DFC4; Tue, 3 Jul 2018 17:50:55 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-148.ams2.redhat.com [10.36.117.148]) by smtp.corp.redhat.com (Postfix) with ESMTP id B19CB20180F4; Tue, 3 Jul 2018 17:50:54 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Tue, 3 Jul 2018 19:50:49 +0200 Message-Id: <20180703175049.27669-3-kwolf@redhat.com> In-Reply-To: <20180703175049.27669-1-kwolf@redhat.com> References: <20180703175049.27669-1-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Tue, 03 Jul 2018 17:50:55 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Tue, 03 Jul 2018 17:50:55 +0000 (UTC) for IP:'10.11.54.4' DOMAIN:'int-mx04.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'kwolf@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH 2/2] test-bdrv-drain: Test bdrv_append() to drained node X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org, mreitz@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Signed-off-by: Kevin Wolf --- tests/test-bdrv-drain.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c index 291a050f86..17bb8508ae 100644 --- a/tests/test-bdrv-drain.c +++ b/tests/test-bdrv-drain.c @@ -1250,6 +1250,47 @@ static void test_detach_by_driver_cb(void) test_detach_indirect(false); } =20 +static void test_append_to_drained(void) +{ + BlockBackend *blk; + BlockDriverState *base, *overlay; + BDRVTestState *base_s, *overlay_s; + + blk =3D blk_new(BLK_PERM_ALL, BLK_PERM_ALL); + base =3D bdrv_new_open_driver(&bdrv_test, "base", BDRV_O_RDWR, &error_= abort); + base_s =3D base->opaque; + blk_insert_bs(blk, base, &error_abort); + + overlay =3D bdrv_new_open_driver(&bdrv_test, "overlay", BDRV_O_RDWR, + &error_abort); + overlay_s =3D overlay->opaque; + + do_drain_begin(BDRV_DRAIN, base); + g_assert_cmpint(base->quiesce_counter, =3D=3D, 1); + g_assert_cmpint(base_s->drain_count, =3D=3D, 1); + g_assert_cmpint(base->in_flight, =3D=3D, 0); + + /* Takes ownership of overlay, so we don't have to unref it later */ + bdrv_append(overlay, base, &error_abort); + g_assert_cmpint(base->in_flight, =3D=3D, 0); + g_assert_cmpint(overlay->in_flight, =3D=3D, 0); + + g_assert_cmpint(base->quiesce_counter, =3D=3D, 1); + g_assert_cmpint(base_s->drain_count, =3D=3D, 1); + g_assert_cmpint(overlay->quiesce_counter, =3D=3D, 1); + g_assert_cmpint(overlay_s->drain_count, =3D=3D, 1); + + do_drain_end(BDRV_DRAIN, base); + + g_assert_cmpint(base->quiesce_counter, =3D=3D, 0); + g_assert_cmpint(base_s->drain_count, =3D=3D, 0); + g_assert_cmpint(overlay->quiesce_counter, =3D=3D, 0); + g_assert_cmpint(overlay_s->drain_count, =3D=3D, 0); + + bdrv_unref(base); + blk_unref(blk); +} + int main(int argc, char **argv) { int ret; @@ -1308,6 +1349,8 @@ int main(int argc, char **argv) g_test_add_func("/bdrv-drain/detach/parent_cb", test_detach_by_parent_= cb); g_test_add_func("/bdrv-drain/detach/driver_cb", test_detach_by_driver_= cb); =20 + g_test_add_func("/bdrv-drain/attach/drain", test_append_to_drained); + ret =3D g_test_run(); qemu_event_destroy(&done_event); return ret; --=20 2.13.6