From nobody Sun Feb 8 14:11:01 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1667911683; cv=none; d=zohomail.com; s=zohoarc; b=aFvLNyQPa0xvaEi/oo1wkTuUMw0V/e7+WesYvwEdlYZK12/bVUrq7MBBmw/ExEXaSdBVacY2KO1lrWUj8j23vAJRZg/kuMad+hubsRMlm84ZNLvuFAJ7xHio1Kd17dJscl6d9ERK9Qcolwj/vunkY13Q/8syvopWLz9vCd3I8sY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1667911683; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=rGmw5zrEx1mh/JyNoydhjgVY5S/H434ZqGXJo+H5UtM=; b=jDhbgjamZb+yMK5suxYb253YTIWOQVE4bum0R2V4S9IT6WhJU4/O+ZwJw1HD+h1pc26QZ42hK3JDGcFn8q+6+z9TstI8v0akZnObmYC0L6ccm0U/PLOmxAH/xwr7quNzmi3MhBIaNMAdOzgTbKsidp42hSzeZ49+Q7kQjrO/z9I= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1667911683414903.3223311208105; Tue, 8 Nov 2022 04:48:03 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1osNsG-0008Fm-64; Tue, 08 Nov 2022 07:38:40 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1osNrs-0007nH-Lq for qemu-devel@nongnu.org; Tue, 08 Nov 2022 07:38:17 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1osNrj-00014Y-8H for qemu-devel@nongnu.org; Tue, 08 Nov 2022 07:38:15 -0500 Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-274-GzOm_B5VOEuXvvNq34mtWw-1; Tue, 08 Nov 2022 07:38:05 -0500 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 44AF1858F17; Tue, 8 Nov 2022 12:38:05 +0000 (UTC) Received: from merkur.redhat.com (unknown [10.39.193.118]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0E4479E70; Tue, 8 Nov 2022 12:38:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1667911086; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=rGmw5zrEx1mh/JyNoydhjgVY5S/H434ZqGXJo+H5UtM=; b=cH9DSXvkEzT1e+n797TL4YX8RoTxzF06L/okxB2YR+cJaQxVeR4993h6VLZER9Z8e6rFd1 NNA+Re0c80x9tOfTH/2Gq2jQ2el8nlsHkPpxISPA3gH8pfMAkErUWoB1r7GFXfqSyVN0Z2 nbU4qLy/H/+eIAdlqW+Uc66qX5tdZtU= X-MC-Unique: GzOm_B5VOEuXvvNq34mtWw-1 From: Kevin Wolf To: qemu-block@nongnu.org Cc: kwolf@redhat.com, eesposit@redhat.com, stefanha@redhat.com, hreitz@redhat.com, pbonzini@redhat.com, qemu-devel@nongnu.org Subject: [PATCH 09/13] block: Remove subtree drains Date: Tue, 8 Nov 2022 13:37:34 +0100 Message-Id: <20221108123738.530873-10-kwolf@redhat.com> In-Reply-To: <20221108123738.530873-1-kwolf@redhat.com> References: <20221108123738.530873-1-kwolf@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.1 on 10.11.54.5 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=kwolf@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1667911685344100003 Content-Type: text/plain; charset="utf-8" Subtree drains are not used any more. Remove them. After this, BdrvChildClass.attach/detach() don't poll any more. Signed-off-by: Kevin Wolf Reviewed-by: Hanna Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- include/block/block-io.h | 18 +-- include/block/block_int-common.h | 1 - include/block/block_int-io.h | 12 -- block.c | 20 +-- block/io.c | 121 +++----------- tests/unit/test-bdrv-drain.c | 261 ++----------------------------- 6 files changed, 44 insertions(+), 389 deletions(-) diff --git a/include/block/block-io.h b/include/block/block-io.h index 97e9ae8bee..c35cb1e53f 100644 --- a/include/block/block-io.h +++ b/include/block/block-io.h @@ -303,8 +303,7 @@ void bdrv_parent_drained_end_single(BdrvChild *c); /** * bdrv_drain_poll: * - * Poll for pending requests in @bs, its parents (except for @ignore_paren= t), - * and if @recursive is true its children as well (used for subtree drain). + * Poll for pending requests in @bs and its parents (except for @ignore_pa= rent). * * If @ignore_bds_parents is true, parents that are BlockDriverStates must * ignore the drain request because they will be drained separately (used = for @@ -312,8 +311,8 @@ void bdrv_parent_drained_end_single(BdrvChild *c); * * This is part of bdrv_drained_begin. */ -bool bdrv_drain_poll(BlockDriverState *bs, bool recursive, - BdrvChild *ignore_parent, bool ignore_bds_parents); +bool bdrv_drain_poll(BlockDriverState *bs, BdrvChild *ignore_parent, + bool ignore_bds_parents); =20 /** * bdrv_drained_begin: @@ -334,12 +333,6 @@ void bdrv_drained_begin(BlockDriverState *bs); void bdrv_do_drained_begin_quiesce(BlockDriverState *bs, BdrvChild *parent, bool ignore_bds_pare= nts); =20 -/** - * Like bdrv_drained_begin, but recursively begins a quiesced section for - * exclusive access to all child nodes as well. - */ -void bdrv_subtree_drained_begin(BlockDriverState *bs); - /** * bdrv_drained_end: * @@ -353,9 +346,4 @@ void bdrv_subtree_drained_begin(BlockDriverState *bs); */ void bdrv_drained_end(BlockDriverState *bs); =20 -/** - * End a quiescent section started by bdrv_subtree_drained_begin(). - */ -void bdrv_subtree_drained_end(BlockDriverState *bs); - #endif /* BLOCK_IO_H */ diff --git a/include/block/block_int-common.h b/include/block/block_int-com= mon.h index 6504db4fd9..65ee5fcbec 100644 --- a/include/block/block_int-common.h +++ b/include/block/block_int-common.h @@ -1184,7 +1184,6 @@ struct BlockDriverState { =20 /* Accessed with atomic ops. */ int quiesce_counter; - int recursive_quiesce_counter; =20 unsigned int write_gen; /* Current data generation */ =20 diff --git a/include/block/block_int-io.h b/include/block/block_int-io.h index 4b0b3e17ef..8bc061ebb8 100644 --- a/include/block/block_int-io.h +++ b/include/block/block_int-io.h @@ -179,16 +179,4 @@ void bdrv_bsc_invalidate_range(BlockDriverState *bs, */ void bdrv_bsc_fill(BlockDriverState *bs, int64_t offset, int64_t bytes); =20 - -/* - * "I/O or GS" API functions. These functions can run without - * the BQL, but only in one specific iothread/main loop. - * - * See include/block/block-io.h for more information about - * the "I/O or GS" API. - */ - -void bdrv_apply_subtree_drain(BdrvChild *child, BlockDriverState *new_pare= nt); -void bdrv_unapply_subtree_drain(BdrvChild *child, BlockDriverState *old_pa= rent); - #endif /* BLOCK_INT_IO_H */ diff --git a/block.c b/block.c index 43b893dd6c..9d082631d9 100644 --- a/block.c +++ b/block.c @@ -1224,7 +1224,7 @@ static void bdrv_child_cb_drained_begin(BdrvChild *ch= ild) static bool bdrv_child_cb_drained_poll(BdrvChild *child) { BlockDriverState *bs =3D child->opaque; - return bdrv_drain_poll(bs, false, NULL, false); + return bdrv_drain_poll(bs, NULL, false); } =20 static void bdrv_child_cb_drained_end(BdrvChild *child) @@ -1474,8 +1474,6 @@ static void bdrv_child_cb_attach(BdrvChild *child) assert(!bs->file); bs->file =3D child; } - - bdrv_apply_subtree_drain(child, bs); } =20 static void bdrv_child_cb_detach(BdrvChild *child) @@ -1486,8 +1484,6 @@ static void bdrv_child_cb_detach(BdrvChild *child) bdrv_backing_detach(child); } =20 - bdrv_unapply_subtree_drain(child, bs); - assert_bdrv_graph_writable(bs); QLIST_REMOVE(child, next); if (child =3D=3D bs->backing) { @@ -2843,9 +2839,6 @@ static void bdrv_replace_child_noperm(BdrvChild *chil= d, } =20 if (old_bs) { - /* Detach first so that the recursive drain sections coming from @= child - * are already gone and we only end the drain sections that came f= rom - * elsewhere. */ if (child->klass->detach) { child->klass->detach(child); } @@ -2860,17 +2853,14 @@ static void bdrv_replace_child_noperm(BdrvChild *ch= ild, QLIST_INSERT_HEAD(&new_bs->parents, child, next_parent); =20 /* - * Detaching the old node may have led to the new node's - * quiesce_counter having been decreased. Not a problem, we - * just need to recognize this here and then invoke - * drained_end appropriately more often. + * Polling in bdrv_parent_drained_begin_single() may have led to t= he new + * node's quiesce_counter having been decreased. Not a problem, w= e just + * need to recognize this here and then invoke drained_end appropr= iately + * more often. */ assert(new_bs->quiesce_counter <=3D new_bs_quiesce_counter); drain_saldo +=3D new_bs->quiesce_counter - new_bs_quiesce_counter; =20 - /* Attach only after starting new drained sections, so that recurs= ive - * drain sections coming from @child don't get an extra .drained_b= egin - * callback. */ if (child->klass->attach) { child->klass->attach(child); } diff --git a/block/io.c b/block/io.c index c520183fb7..870a25d7a5 100644 --- a/block/io.c +++ b/block/io.c @@ -235,17 +235,15 @@ typedef struct { BlockDriverState *bs; bool done; bool begin; - bool recursive; bool poll; BdrvChild *parent; bool ignore_bds_parents; } BdrvCoDrainData; =20 /* Returns true if BDRV_POLL_WHILE() should go into a blocking aio_poll() = */ -bool bdrv_drain_poll(BlockDriverState *bs, bool recursive, - BdrvChild *ignore_parent, bool ignore_bds_parents) +bool bdrv_drain_poll(BlockDriverState *bs, BdrvChild *ignore_parent, + bool ignore_bds_parents) { - BdrvChild *child, *next; IO_OR_GS_CODE(); =20 if (bdrv_parent_drained_poll(bs, ignore_parent, ignore_bds_parents)) { @@ -256,29 +254,19 @@ bool bdrv_drain_poll(BlockDriverState *bs, bool recur= sive, return true; } =20 - if (recursive) { - assert(!ignore_bds_parents); - QLIST_FOREACH_SAFE(child, &bs->children, next, next) { - if (bdrv_drain_poll(child->bs, recursive, child, false)) { - return true; - } - } - } - return false; } =20 -static bool bdrv_drain_poll_top_level(BlockDriverState *bs, bool recursive, +static bool bdrv_drain_poll_top_level(BlockDriverState *bs, BdrvChild *ignore_parent) { - return bdrv_drain_poll(bs, recursive, ignore_parent, false); + return bdrv_drain_poll(bs, ignore_parent, false); } =20 -static void bdrv_do_drained_begin(BlockDriverState *bs, bool recursive, - BdrvChild *parent, bool ignore_bds_paren= ts, - bool poll); -static void bdrv_do_drained_end(BlockDriverState *bs, bool recursive, - BdrvChild *parent, bool ignore_bds_parents= ); +static void bdrv_do_drained_begin(BlockDriverState *bs, BdrvChild *parent, + bool ignore_bds_parents, bool poll); +static void bdrv_do_drained_end(BlockDriverState *bs, BdrvChild *parent, + bool ignore_bds_parents); =20 static void bdrv_co_drain_bh_cb(void *opaque) { @@ -291,12 +279,11 @@ static void bdrv_co_drain_bh_cb(void *opaque) aio_context_acquire(ctx); bdrv_dec_in_flight(bs); if (data->begin) { - bdrv_do_drained_begin(bs, data->recursive, data->parent, - data->ignore_bds_parents, data->poll); + bdrv_do_drained_begin(bs, data->parent, data->ignore_bds_paren= ts, + data->poll); } else { assert(!data->poll); - bdrv_do_drained_end(bs, data->recursive, data->parent, - data->ignore_bds_parents); + bdrv_do_drained_end(bs, data->parent, data->ignore_bds_parents= ); } aio_context_release(ctx); } else { @@ -309,7 +296,7 @@ static void bdrv_co_drain_bh_cb(void *opaque) } =20 static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs, - bool begin, bool recursive, + bool begin, BdrvChild *parent, bool ignore_bds_parents, bool poll) @@ -328,7 +315,6 @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDr= iverState *bs, .bs =3D bs, .done =3D false, .begin =3D begin, - .recursive =3D recursive, .parent =3D parent, .ignore_bds_parents =3D ignore_bds_parents, .poll =3D poll, @@ -379,29 +365,16 @@ void bdrv_do_drained_begin_quiesce(BlockDriverState *= bs, } } =20 -static void bdrv_do_drained_begin(BlockDriverState *bs, bool recursive, - BdrvChild *parent, bool ignore_bds_paren= ts, - bool poll) +static void bdrv_do_drained_begin(BlockDriverState *bs, BdrvChild *parent, + bool ignore_bds_parents, bool poll) { - BdrvChild *child, *next; - if (qemu_in_coroutine()) { - bdrv_co_yield_to_drain(bs, true, recursive, parent, ignore_bds_par= ents, - poll); + bdrv_co_yield_to_drain(bs, true, parent, ignore_bds_parents, poll); return; } =20 bdrv_do_drained_begin_quiesce(bs, parent, ignore_bds_parents); =20 - if (recursive) { - assert(!ignore_bds_parents); - bs->recursive_quiesce_counter++; - QLIST_FOREACH_SAFE(child, &bs->children, next, next) { - bdrv_do_drained_begin(child->bs, true, child, ignore_bds_paren= ts, - false); - } - } - /* * Wait for drained requests to finish. * @@ -413,35 +386,27 @@ static void bdrv_do_drained_begin(BlockDriverState *b= s, bool recursive, */ if (poll) { assert(!ignore_bds_parents); - BDRV_POLL_WHILE(bs, bdrv_drain_poll_top_level(bs, recursive, paren= t)); + BDRV_POLL_WHILE(bs, bdrv_drain_poll_top_level(bs, parent)); } } =20 void bdrv_drained_begin(BlockDriverState *bs) { IO_OR_GS_CODE(); - bdrv_do_drained_begin(bs, false, NULL, false, true); -} - -void bdrv_subtree_drained_begin(BlockDriverState *bs) -{ - IO_OR_GS_CODE(); - bdrv_do_drained_begin(bs, true, NULL, false, true); + bdrv_do_drained_begin(bs, NULL, false, true); } =20 /** * This function does not poll, nor must any of its recursively called * functions. */ -static void bdrv_do_drained_end(BlockDriverState *bs, bool recursive, - BdrvChild *parent, bool ignore_bds_parents) +static void bdrv_do_drained_end(BlockDriverState *bs, BdrvChild *parent, + bool ignore_bds_parents) { - BdrvChild *child; int old_quiesce_counter; =20 if (qemu_in_coroutine()) { - bdrv_co_yield_to_drain(bs, false, recursive, parent, ignore_bds_pa= rents, - false); + bdrv_co_yield_to_drain(bs, false, parent, ignore_bds_parents, fals= e); return; } assert(bs->quiesce_counter > 0); @@ -456,46 +421,12 @@ static void bdrv_do_drained_end(BlockDriverState *bs,= bool recursive, if (old_quiesce_counter =3D=3D 1) { aio_enable_external(bdrv_get_aio_context(bs)); } - - if (recursive) { - assert(!ignore_bds_parents); - bs->recursive_quiesce_counter--; - QLIST_FOREACH(child, &bs->children, next) { - bdrv_do_drained_end(child->bs, true, child, ignore_bds_parents= ); - } - } } =20 void bdrv_drained_end(BlockDriverState *bs) { IO_OR_GS_CODE(); - bdrv_do_drained_end(bs, false, NULL, false); -} - -void bdrv_subtree_drained_end(BlockDriverState *bs) -{ - IO_OR_GS_CODE(); - bdrv_do_drained_end(bs, true, NULL, false); -} - -void bdrv_apply_subtree_drain(BdrvChild *child, BlockDriverState *new_pare= nt) -{ - int i; - IO_OR_GS_CODE(); - - for (i =3D 0; i < new_parent->recursive_quiesce_counter; i++) { - bdrv_do_drained_begin(child->bs, true, child, false, true); - } -} - -void bdrv_unapply_subtree_drain(BdrvChild *child, BlockDriverState *old_pa= rent) -{ - int i; - IO_OR_GS_CODE(); - - for (i =3D 0; i < old_parent->recursive_quiesce_counter; i++) { - bdrv_do_drained_end(child->bs, true, child, false); - } + bdrv_do_drained_end(bs, NULL, false); } =20 void bdrv_drain(BlockDriverState *bs) @@ -528,7 +459,7 @@ static bool bdrv_drain_all_poll(void) while ((bs =3D bdrv_next_all_states(bs))) { AioContext *aio_context =3D bdrv_get_aio_context(bs); aio_context_acquire(aio_context); - result |=3D bdrv_drain_poll(bs, false, NULL, true); + result |=3D bdrv_drain_poll(bs, NULL, true); aio_context_release(aio_context); } =20 @@ -553,7 +484,7 @@ void bdrv_drain_all_begin(void) GLOBAL_STATE_CODE(); =20 if (qemu_in_coroutine()) { - bdrv_co_yield_to_drain(NULL, true, false, NULL, true, true); + bdrv_co_yield_to_drain(NULL, true, NULL, true, true); return; } =20 @@ -578,7 +509,7 @@ void bdrv_drain_all_begin(void) AioContext *aio_context =3D bdrv_get_aio_context(bs); =20 aio_context_acquire(aio_context); - bdrv_do_drained_begin(bs, false, NULL, true, false); + bdrv_do_drained_begin(bs, NULL, true, false); aio_context_release(aio_context); } =20 @@ -598,7 +529,7 @@ void bdrv_drain_all_end_quiesce(BlockDriverState *bs) g_assert(!bs->refcnt); =20 while (bs->quiesce_counter) { - bdrv_do_drained_end(bs, false, NULL, true); + bdrv_do_drained_end(bs, NULL, true); } } =20 @@ -620,7 +551,7 @@ void bdrv_drain_all_end(void) AioContext *aio_context =3D bdrv_get_aio_context(bs); =20 aio_context_acquire(aio_context); - bdrv_do_drained_end(bs, false, NULL, true); + bdrv_do_drained_end(bs, NULL, true); aio_context_release(aio_context); } =20 diff --git a/tests/unit/test-bdrv-drain.c b/tests/unit/test-bdrv-drain.c index 695519ee02..dda08de8db 100644 --- a/tests/unit/test-bdrv-drain.c +++ b/tests/unit/test-bdrv-drain.c @@ -156,7 +156,6 @@ static void call_in_coroutine(void (*entry)(void)) enum drain_type { BDRV_DRAIN_ALL, BDRV_DRAIN, - BDRV_SUBTREE_DRAIN, DRAIN_TYPE_MAX, }; =20 @@ -165,7 +164,6 @@ static void do_drain_begin(enum drain_type drain_type, = BlockDriverState *bs) switch (drain_type) { case BDRV_DRAIN_ALL: bdrv_drain_all_begin(); break; case BDRV_DRAIN: bdrv_drained_begin(bs); break; - case BDRV_SUBTREE_DRAIN: bdrv_subtree_drained_begin(bs); break; default: g_assert_not_reached(); } } @@ -175,7 +173,6 @@ static void do_drain_end(enum drain_type drain_type, Bl= ockDriverState *bs) switch (drain_type) { case BDRV_DRAIN_ALL: bdrv_drain_all_end(); break; case BDRV_DRAIN: bdrv_drained_end(bs); break; - case BDRV_SUBTREE_DRAIN: bdrv_subtree_drained_end(bs); break; default: g_assert_not_reached(); } } @@ -271,11 +268,6 @@ static void test_drv_cb_drain(void) test_drv_cb_common(BDRV_DRAIN, false); } =20 -static void test_drv_cb_drain_subtree(void) -{ - test_drv_cb_common(BDRV_SUBTREE_DRAIN, true); -} - static void test_drv_cb_co_drain_all(void) { call_in_coroutine(test_drv_cb_drain_all); @@ -286,11 +278,6 @@ static void test_drv_cb_co_drain(void) call_in_coroutine(test_drv_cb_drain); } =20 -static void test_drv_cb_co_drain_subtree(void) -{ - call_in_coroutine(test_drv_cb_drain_subtree); -} - static void test_quiesce_common(enum drain_type drain_type, bool recursive) { BlockBackend *blk; @@ -332,11 +319,6 @@ static void test_quiesce_drain(void) test_quiesce_common(BDRV_DRAIN, false); } =20 -static void test_quiesce_drain_subtree(void) -{ - test_quiesce_common(BDRV_SUBTREE_DRAIN, true); -} - static void test_quiesce_co_drain_all(void) { call_in_coroutine(test_quiesce_drain_all); @@ -347,11 +329,6 @@ static void test_quiesce_co_drain(void) call_in_coroutine(test_quiesce_drain); } =20 -static void test_quiesce_co_drain_subtree(void) -{ - call_in_coroutine(test_quiesce_drain_subtree); -} - static void test_nested(void) { BlockBackend *blk; @@ -402,158 +379,6 @@ static void test_nested(void) blk_unref(blk); } =20 -static void test_multiparent(void) -{ - BlockBackend *blk_a, *blk_b; - BlockDriverState *bs_a, *bs_b, *backing; - BDRVTestState *a_s, *b_s, *backing_s; - - blk_a =3D blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); - bs_a =3D bdrv_new_open_driver(&bdrv_test, "test-node-a", BDRV_O_RDWR, - &error_abort); - a_s =3D bs_a->opaque; - blk_insert_bs(blk_a, bs_a, &error_abort); - - blk_b =3D blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); - bs_b =3D bdrv_new_open_driver(&bdrv_test, "test-node-b", BDRV_O_RDWR, - &error_abort); - b_s =3D bs_b->opaque; - blk_insert_bs(blk_b, bs_b, &error_abort); - - backing =3D bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abor= t); - backing_s =3D backing->opaque; - bdrv_set_backing_hd(bs_a, backing, &error_abort); - bdrv_set_backing_hd(bs_b, backing, &error_abort); - - g_assert_cmpint(bs_a->quiesce_counter, =3D=3D, 0); - g_assert_cmpint(bs_b->quiesce_counter, =3D=3D, 0); - g_assert_cmpint(backing->quiesce_counter, =3D=3D, 0); - g_assert_cmpint(a_s->drain_count, =3D=3D, 0); - g_assert_cmpint(b_s->drain_count, =3D=3D, 0); - g_assert_cmpint(backing_s->drain_count, =3D=3D, 0); - - do_drain_begin(BDRV_SUBTREE_DRAIN, bs_a); - - g_assert_cmpint(bs_a->quiesce_counter, =3D=3D, 1); - g_assert_cmpint(bs_b->quiesce_counter, =3D=3D, 1); - g_assert_cmpint(backing->quiesce_counter, =3D=3D, 1); - g_assert_cmpint(a_s->drain_count, =3D=3D, 1); - g_assert_cmpint(b_s->drain_count, =3D=3D, 1); - g_assert_cmpint(backing_s->drain_count, =3D=3D, 1); - - do_drain_begin(BDRV_SUBTREE_DRAIN, bs_b); - - g_assert_cmpint(bs_a->quiesce_counter, =3D=3D, 2); - g_assert_cmpint(bs_b->quiesce_counter, =3D=3D, 2); - g_assert_cmpint(backing->quiesce_counter, =3D=3D, 2); - g_assert_cmpint(a_s->drain_count, =3D=3D, 2); - g_assert_cmpint(b_s->drain_count, =3D=3D, 2); - g_assert_cmpint(backing_s->drain_count, =3D=3D, 2); - - do_drain_end(BDRV_SUBTREE_DRAIN, bs_b); - - g_assert_cmpint(bs_a->quiesce_counter, =3D=3D, 1); - g_assert_cmpint(bs_b->quiesce_counter, =3D=3D, 1); - g_assert_cmpint(backing->quiesce_counter, =3D=3D, 1); - g_assert_cmpint(a_s->drain_count, =3D=3D, 1); - g_assert_cmpint(b_s->drain_count, =3D=3D, 1); - g_assert_cmpint(backing_s->drain_count, =3D=3D, 1); - - do_drain_end(BDRV_SUBTREE_DRAIN, bs_a); - - g_assert_cmpint(bs_a->quiesce_counter, =3D=3D, 0); - g_assert_cmpint(bs_b->quiesce_counter, =3D=3D, 0); - g_assert_cmpint(backing->quiesce_counter, =3D=3D, 0); - g_assert_cmpint(a_s->drain_count, =3D=3D, 0); - g_assert_cmpint(b_s->drain_count, =3D=3D, 0); - g_assert_cmpint(backing_s->drain_count, =3D=3D, 0); - - bdrv_unref(backing); - bdrv_unref(bs_a); - bdrv_unref(bs_b); - blk_unref(blk_a); - blk_unref(blk_b); -} - -static void test_graph_change_drain_subtree(void) -{ - BlockBackend *blk_a, *blk_b; - BlockDriverState *bs_a, *bs_b, *backing; - BDRVTestState *a_s, *b_s, *backing_s; - - blk_a =3D blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); - bs_a =3D bdrv_new_open_driver(&bdrv_test, "test-node-a", BDRV_O_RDWR, - &error_abort); - a_s =3D bs_a->opaque; - blk_insert_bs(blk_a, bs_a, &error_abort); - - blk_b =3D blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL); - bs_b =3D bdrv_new_open_driver(&bdrv_test, "test-node-b", BDRV_O_RDWR, - &error_abort); - b_s =3D bs_b->opaque; - blk_insert_bs(blk_b, bs_b, &error_abort); - - backing =3D bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abor= t); - backing_s =3D backing->opaque; - bdrv_set_backing_hd(bs_a, backing, &error_abort); - - g_assert_cmpint(bs_a->quiesce_counter, =3D=3D, 0); - g_assert_cmpint(bs_b->quiesce_counter, =3D=3D, 0); - g_assert_cmpint(backing->quiesce_counter, =3D=3D, 0); - g_assert_cmpint(a_s->drain_count, =3D=3D, 0); - g_assert_cmpint(b_s->drain_count, =3D=3D, 0); - g_assert_cmpint(backing_s->drain_count, =3D=3D, 0); - - do_drain_begin(BDRV_SUBTREE_DRAIN, bs_a); - do_drain_begin(BDRV_SUBTREE_DRAIN, bs_a); - do_drain_begin(BDRV_SUBTREE_DRAIN, bs_a); - do_drain_begin(BDRV_SUBTREE_DRAIN, bs_b); - do_drain_begin(BDRV_SUBTREE_DRAIN, bs_b); - - bdrv_set_backing_hd(bs_b, backing, &error_abort); - g_assert_cmpint(bs_a->quiesce_counter, =3D=3D, 5); - g_assert_cmpint(bs_b->quiesce_counter, =3D=3D, 5); - g_assert_cmpint(backing->quiesce_counter, =3D=3D, 5); - g_assert_cmpint(a_s->drain_count, =3D=3D, 5); - g_assert_cmpint(b_s->drain_count, =3D=3D, 5); - g_assert_cmpint(backing_s->drain_count, =3D=3D, 5); - - bdrv_set_backing_hd(bs_b, NULL, &error_abort); - g_assert_cmpint(bs_a->quiesce_counter, =3D=3D, 3); - g_assert_cmpint(bs_b->quiesce_counter, =3D=3D, 2); - g_assert_cmpint(backing->quiesce_counter, =3D=3D, 3); - g_assert_cmpint(a_s->drain_count, =3D=3D, 3); - g_assert_cmpint(b_s->drain_count, =3D=3D, 2); - g_assert_cmpint(backing_s->drain_count, =3D=3D, 3); - - bdrv_set_backing_hd(bs_b, backing, &error_abort); - g_assert_cmpint(bs_a->quiesce_counter, =3D=3D, 5); - g_assert_cmpint(bs_b->quiesce_counter, =3D=3D, 5); - g_assert_cmpint(backing->quiesce_counter, =3D=3D, 5); - g_assert_cmpint(a_s->drain_count, =3D=3D, 5); - g_assert_cmpint(b_s->drain_count, =3D=3D, 5); - g_assert_cmpint(backing_s->drain_count, =3D=3D, 5); - - do_drain_end(BDRV_SUBTREE_DRAIN, bs_b); - do_drain_end(BDRV_SUBTREE_DRAIN, bs_b); - do_drain_end(BDRV_SUBTREE_DRAIN, bs_a); - do_drain_end(BDRV_SUBTREE_DRAIN, bs_a); - do_drain_end(BDRV_SUBTREE_DRAIN, bs_a); - - g_assert_cmpint(bs_a->quiesce_counter, =3D=3D, 0); - g_assert_cmpint(bs_b->quiesce_counter, =3D=3D, 0); - g_assert_cmpint(backing->quiesce_counter, =3D=3D, 0); - g_assert_cmpint(a_s->drain_count, =3D=3D, 0); - g_assert_cmpint(b_s->drain_count, =3D=3D, 0); - g_assert_cmpint(backing_s->drain_count, =3D=3D, 0); - - bdrv_unref(backing); - bdrv_unref(bs_a); - bdrv_unref(bs_b); - blk_unref(blk_a); - blk_unref(blk_b); -} - static void test_graph_change_drain_all(void) { BlockBackend *blk_a, *blk_b; @@ -773,12 +598,6 @@ static void test_iothread_drain(void) test_iothread_common(BDRV_DRAIN, 1); } =20 -static void test_iothread_drain_subtree(void) -{ - test_iothread_common(BDRV_SUBTREE_DRAIN, 0); - test_iothread_common(BDRV_SUBTREE_DRAIN, 1); -} - =20 typedef struct TestBlockJob { BlockJob common; @@ -863,7 +682,6 @@ enum test_job_result { enum test_job_drain_node { TEST_JOB_DRAIN_SRC, TEST_JOB_DRAIN_SRC_CHILD, - TEST_JOB_DRAIN_SRC_PARENT, }; =20 static void test_blockjob_common_drain_node(enum drain_type drain_type, @@ -901,9 +719,6 @@ static void test_blockjob_common_drain_node(enum drain_= type drain_type, case TEST_JOB_DRAIN_SRC_CHILD: drain_bs =3D src_backing; break; - case TEST_JOB_DRAIN_SRC_PARENT: - drain_bs =3D src_overlay; - break; default: g_assert_not_reached(); } @@ -1055,10 +870,6 @@ static void test_blockjob_common(enum drain_type drai= n_type, bool use_iothread, TEST_JOB_DRAIN_SRC); test_blockjob_common_drain_node(drain_type, use_iothread, result, TEST_JOB_DRAIN_SRC_CHILD); - if (drain_type =3D=3D BDRV_SUBTREE_DRAIN) { - test_blockjob_common_drain_node(drain_type, use_iothread, result, - TEST_JOB_DRAIN_SRC_PARENT); - } } =20 static void test_blockjob_drain_all(void) @@ -1071,11 +882,6 @@ static void test_blockjob_drain(void) test_blockjob_common(BDRV_DRAIN, false, TEST_JOB_SUCCESS); } =20 -static void test_blockjob_drain_subtree(void) -{ - test_blockjob_common(BDRV_SUBTREE_DRAIN, false, TEST_JOB_SUCCESS); -} - static void test_blockjob_error_drain_all(void) { test_blockjob_common(BDRV_DRAIN_ALL, false, TEST_JOB_FAIL_RUN); @@ -1088,12 +894,6 @@ static void test_blockjob_error_drain(void) test_blockjob_common(BDRV_DRAIN, false, TEST_JOB_FAIL_PREPARE); } =20 -static void test_blockjob_error_drain_subtree(void) -{ - test_blockjob_common(BDRV_SUBTREE_DRAIN, false, TEST_JOB_FAIL_RUN); - test_blockjob_common(BDRV_SUBTREE_DRAIN, false, TEST_JOB_FAIL_PREPARE); -} - static void test_blockjob_iothread_drain_all(void) { test_blockjob_common(BDRV_DRAIN_ALL, true, TEST_JOB_SUCCESS); @@ -1104,11 +904,6 @@ static void test_blockjob_iothread_drain(void) test_blockjob_common(BDRV_DRAIN, true, TEST_JOB_SUCCESS); } =20 -static void test_blockjob_iothread_drain_subtree(void) -{ - test_blockjob_common(BDRV_SUBTREE_DRAIN, true, TEST_JOB_SUCCESS); -} - static void test_blockjob_iothread_error_drain_all(void) { test_blockjob_common(BDRV_DRAIN_ALL, true, TEST_JOB_FAIL_RUN); @@ -1121,12 +916,6 @@ static void test_blockjob_iothread_error_drain(void) test_blockjob_common(BDRV_DRAIN, true, TEST_JOB_FAIL_PREPARE); } =20 -static void test_blockjob_iothread_error_drain_subtree(void) -{ - test_blockjob_common(BDRV_SUBTREE_DRAIN, true, TEST_JOB_FAIL_RUN); - test_blockjob_common(BDRV_SUBTREE_DRAIN, true, TEST_JOB_FAIL_PREPARE); -} - =20 typedef struct BDRVTestTopState { BdrvChild *wait_child; @@ -1273,14 +1062,6 @@ static void do_test_delete_by_drain(bool detach_inst= ead_of_delete, bdrv_drain(child_bs); bdrv_unref(child_bs); break; - case BDRV_SUBTREE_DRAIN: - /* Would have to ref/unref bs here for !detach_instead_of_delete, = but - * then the whole test becomes pointless because the graph changes - * don't occur during the drain any more. */ - assert(detach_instead_of_delete); - bdrv_subtree_drained_begin(bs); - bdrv_subtree_drained_end(bs); - break; case BDRV_DRAIN_ALL: bdrv_drain_all_begin(); bdrv_drain_all_end(); @@ -1315,11 +1096,6 @@ static void test_detach_by_drain(void) do_test_delete_by_drain(true, BDRV_DRAIN); } =20 -static void test_detach_by_drain_subtree(void) -{ - do_test_delete_by_drain(true, BDRV_SUBTREE_DRAIN); -} - =20 struct detach_by_parent_data { BlockDriverState *parent_b; @@ -1452,7 +1228,10 @@ static void test_detach_indirect(bool by_parent_cb) g_assert(acb !=3D NULL); =20 /* Drain and check the expected result */ - bdrv_subtree_drained_begin(parent_b); + bdrv_drained_begin(parent_b); + bdrv_drained_begin(a); + bdrv_drained_begin(b); + bdrv_drained_begin(c); =20 g_assert(detach_by_parent_data.child_c !=3D NULL); =20 @@ -1467,12 +1246,15 @@ static void test_detach_indirect(bool by_parent_cb) g_assert(QLIST_NEXT(child_a, next) =3D=3D NULL); =20 g_assert_cmpint(parent_a->quiesce_counter, =3D=3D, 1); - g_assert_cmpint(parent_b->quiesce_counter, =3D=3D, 1); + g_assert_cmpint(parent_b->quiesce_counter, =3D=3D, 3); g_assert_cmpint(a->quiesce_counter, =3D=3D, 1); - g_assert_cmpint(b->quiesce_counter, =3D=3D, 0); + g_assert_cmpint(b->quiesce_counter, =3D=3D, 1); g_assert_cmpint(c->quiesce_counter, =3D=3D, 1); =20 - bdrv_subtree_drained_end(parent_b); + bdrv_drained_end(parent_b); + bdrv_drained_end(a); + bdrv_drained_end(b); + bdrv_drained_end(c); =20 bdrv_unref(parent_b); blk_unref(blk); @@ -2202,70 +1984,47 @@ int main(int argc, char **argv) =20 g_test_add_func("/bdrv-drain/driver-cb/drain_all", test_drv_cb_drain_a= ll); g_test_add_func("/bdrv-drain/driver-cb/drain", test_drv_cb_drain); - g_test_add_func("/bdrv-drain/driver-cb/drain_subtree", - test_drv_cb_drain_subtree); =20 g_test_add_func("/bdrv-drain/driver-cb/co/drain_all", test_drv_cb_co_drain_all); g_test_add_func("/bdrv-drain/driver-cb/co/drain", test_drv_cb_co_drain= ); - g_test_add_func("/bdrv-drain/driver-cb/co/drain_subtree", - test_drv_cb_co_drain_subtree); - =20 g_test_add_func("/bdrv-drain/quiesce/drain_all", test_quiesce_drain_al= l); g_test_add_func("/bdrv-drain/quiesce/drain", test_quiesce_drain); - g_test_add_func("/bdrv-drain/quiesce/drain_subtree", - test_quiesce_drain_subtree); =20 g_test_add_func("/bdrv-drain/quiesce/co/drain_all", test_quiesce_co_drain_all); g_test_add_func("/bdrv-drain/quiesce/co/drain", test_quiesce_co_drain); - g_test_add_func("/bdrv-drain/quiesce/co/drain_subtree", - test_quiesce_co_drain_subtree); =20 g_test_add_func("/bdrv-drain/nested", test_nested); - g_test_add_func("/bdrv-drain/multiparent", test_multiparent); =20 - g_test_add_func("/bdrv-drain/graph-change/drain_subtree", - test_graph_change_drain_subtree); g_test_add_func("/bdrv-drain/graph-change/drain_all", test_graph_change_drain_all); =20 g_test_add_func("/bdrv-drain/iothread/drain_all", test_iothread_drain_= all); g_test_add_func("/bdrv-drain/iothread/drain", test_iothread_drain); - g_test_add_func("/bdrv-drain/iothread/drain_subtree", - test_iothread_drain_subtree); =20 g_test_add_func("/bdrv-drain/blockjob/drain_all", test_blockjob_drain_= all); g_test_add_func("/bdrv-drain/blockjob/drain", test_blockjob_drain); - g_test_add_func("/bdrv-drain/blockjob/drain_subtree", - test_blockjob_drain_subtree); =20 g_test_add_func("/bdrv-drain/blockjob/error/drain_all", test_blockjob_error_drain_all); g_test_add_func("/bdrv-drain/blockjob/error/drain", test_blockjob_error_drain); - g_test_add_func("/bdrv-drain/blockjob/error/drain_subtree", - test_blockjob_error_drain_subtree); =20 g_test_add_func("/bdrv-drain/blockjob/iothread/drain_all", test_blockjob_iothread_drain_all); g_test_add_func("/bdrv-drain/blockjob/iothread/drain", test_blockjob_iothread_drain); - g_test_add_func("/bdrv-drain/blockjob/iothread/drain_subtree", - test_blockjob_iothread_drain_subtree); =20 g_test_add_func("/bdrv-drain/blockjob/iothread/error/drain_all", test_blockjob_iothread_error_drain_all); g_test_add_func("/bdrv-drain/blockjob/iothread/error/drain", test_blockjob_iothread_error_drain); - g_test_add_func("/bdrv-drain/blockjob/iothread/error/drain_subtree", - test_blockjob_iothread_error_drain_subtree); =20 g_test_add_func("/bdrv-drain/deletion/drain", test_delete_by_drain); g_test_add_func("/bdrv-drain/detach/drain_all", test_detach_by_drain_a= ll); g_test_add_func("/bdrv-drain/detach/drain", test_detach_by_drain); - g_test_add_func("/bdrv-drain/detach/drain_subtree", test_detach_by_dra= in_subtree); 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 --=20 2.38.1