From nobody Wed Nov 5 05:10:24 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 1532384843088728.819374884764; Mon, 23 Jul 2018 15:27:23 -0700 (PDT) Received: from localhost ([::1]:37154 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fhjIX-0006LO-VB for importer@patchew.org; Mon, 23 Jul 2018 18:27:22 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45746) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fhjDg-00027M-Eg for qemu-devel@nongnu.org; Mon, 23 Jul 2018 18:22:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fhjDf-0007vz-3s for qemu-devel@nongnu.org; Mon, 23 Jul 2018 18:22:20 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:50160 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 1fhjDZ-0007sO-Qb; Mon, 23 Jul 2018 18:22:13 -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 6AE4587A73; Mon, 23 Jul 2018 22:22:13 +0000 (UTC) Received: from probe.bos.redhat.com (dhcp-17-177.bos.redhat.com [10.18.17.177]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0D65620290B2; Mon, 23 Jul 2018 22:22:13 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Mon, 23 Jul 2018 18:22:08 -0400 Message-Id: <20180723222210.11077-6-jsnow@redhat.com> In-Reply-To: <20180723222210.11077-1-jsnow@redhat.com> References: <20180723222210.11077-1-jsnow@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.1]); Mon, 23 Jul 2018 22:22:13 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Mon, 23 Jul 2018 22:22:13 +0000 (UTC) for IP:'10.11.54.4' DOMAIN:'int-mx04.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'jsnow@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 for-3.0 5/7] dirty-bitmaps: clean-up bitmaps loading and migration logic 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: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Fam Zheng , Juan Quintela , qemu-stable@nongnu.org, "Dr. David Alan Gilbert" , Stefan Hajnoczi , Max Reitz , John Snow 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" This patch aims to bring the following behavior: 1. Bitmaps are not loaded on open if BDRV_O_INACTIVE is set, which occurs for incoming migration cases. We will load these persistent bitmaps on invalidate instead. 2. Regardless of the migration circumstances, persistent bitmaps are always flushed to disk on inactivate or close. 3. Bitmaps are read from disk and loaded into memory on any invalidation: A) Normal, RW open B) Migration target invalidation: With or without dirty-bitmaps capability, any bitmaps found on-disk will be loaded. C) Migration source invalidation: If the migration fails and the source QEMU is resumed, it will re-load bitmaps from disk. 4. When using the dirty-bitmaps migration capability, persistent bitmaps are skipped if we are performing a shared storage migration. The destination QEMU will load them from disk on invalidate. (Transient, non-persistent bitmaps still get migrated.) For block migrations, persistent bitmaps are both flushed to disk on the source and migrated live across the migration channel. 5. Persistent bitmaps are not unloaded from memory in the inactivate handler. Instead, they are removed on-store which occurs during inactivate. The effect is functionally the same, but keeps bitmap management more inside the module. Signed-off-by: Vladimir Sementsov-Ogievskiy Signed-off-by: John Snow --- block.c | 4 ---- block/dirty-bitmap.c | 20 -------------------- block/qcow2-bitmap.c | 16 ++++++++++++++++ block/qcow2.c | 5 +++-- include/block/dirty-bitmap.h | 2 +- migration/block-dirty-bitmap.c | 11 ++++++----- 6 files changed, 26 insertions(+), 32 deletions(-) diff --git a/block.c b/block.c index a2fe05ea96..f16bf106d1 100644 --- a/block.c +++ b/block.c @@ -4497,10 +4497,6 @@ static int bdrv_inactivate_recurse(BlockDriverState = *bs, } } =20 - /* At this point persistent bitmaps should be already stored by the fo= rmat - * driver */ - bdrv_release_persistent_dirty_bitmaps(bs); - return 0; } =20 diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c index c9b8a6fd52..e44061fe2e 100644 --- a/block/dirty-bitmap.c +++ b/block/dirty-bitmap.c @@ -383,26 +383,6 @@ void bdrv_release_named_dirty_bitmaps(BlockDriverState= *bs) bdrv_dirty_bitmaps_unlock(bs); } =20 -/** - * Release all persistent dirty bitmaps attached to a BDS (for use in - * bdrv_inactivate_recurse()). - * There must not be any frozen bitmaps attached. - * This function does not remove persistent bitmaps from the storage. - * Called with BQL taken. - */ -void bdrv_release_persistent_dirty_bitmaps(BlockDriverState *bs) -{ - BdrvDirtyBitmap *bm, *next; - - bdrv_dirty_bitmaps_lock(bs); - QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, next) { - if (bdrv_dirty_bitmap_get_persistance(bm)) { - bdrv_release_dirty_bitmap_locked(bm); - } - } - bdrv_dirty_bitmaps_unlock(bs); -} - /** * Remove persistent dirty bitmap from the storage if it exists. * Absence of bitmap is not an error, because we have the following scenar= io: diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c index ba978ad2aa..b5f1b3563d 100644 --- a/block/qcow2-bitmap.c +++ b/block/qcow2-bitmap.c @@ -1418,6 +1418,22 @@ void qcow2_store_persistent_dirty_bitmaps(BlockDrive= rState *bs, Error **errp) g_free(tb); } =20 + QSIMPLEQ_FOREACH(bm, bm_list, entry) { + /* For safety, we remove bitmap after storing. + * We may be here in two cases: + * 1. bdrv_close. It's ok to drop bitmap. + * 2. inactivation. It means migration without 'dirty-bitmaps' + * capability, so bitmaps are not marked with + * BdrvDirtyBitmap.migration flags. It's not bad to drop them t= oo, + * and reload on invalidation. + */ + if (bm->dirty_bitmap =3D=3D NULL) { + continue; + } + + bdrv_release_dirty_bitmap(bs, bm->dirty_bitmap); + } + bitmap_list_free(bm_list); return; =20 diff --git a/block/qcow2.c b/block/qcow2.c index 72d4e67b99..b958cec83d 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1495,8 +1495,9 @@ static int coroutine_fn qcow2_do_open(BlockDriverStat= e *bs, QDict *options, s->autoclear_features &=3D QCOW2_AUTOCLEAR_MASK; } =20 - if (qcow2_load_dirty_bitmaps(bs, &local_err)) { - update_header =3D false; + if (!(bdrv_get_flags(bs) & BDRV_O_INACTIVE)) { + bool header_updated =3D qcow2_load_dirty_bitmaps(bs, &local_err); + update_header =3D update_header && !header_updated; } if (local_err !=3D NULL) { error_propagate(errp, local_err); diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h index 259bd27c40..95c7847ec6 100644 --- a/include/block/dirty-bitmap.h +++ b/include/block/dirty-bitmap.h @@ -26,7 +26,6 @@ BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState = *bs, const char *name); void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitm= ap); void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs); -void bdrv_release_persistent_dirty_bitmaps(BlockDriverState *bs); void bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs, const char *name, Error **errp); @@ -72,6 +71,7 @@ void bdrv_dirty_bitmap_set_persistance(BdrvDirtyBitmap *b= itmap, void bdrv_dirty_bitmap_set_qmp_locked(BdrvDirtyBitmap *bitmap, bool qmp_lo= cked); void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap = *src, Error **errp); +void bdrv_dirty_bitmap_set_migration(BdrvDirtyBitmap *bitmap, bool migrati= on); =20 /* Functions that require manual locking. */ void bdrv_dirty_bitmap_lock(BdrvDirtyBitmap *bitmap); diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c index 477826330c..dac8270d1f 100644 --- a/migration/block-dirty-bitmap.c +++ b/migration/block-dirty-bitmap.c @@ -295,6 +295,12 @@ static int init_dirty_bitmap_migration(void) continue; } =20 + /* Skip persistant bitmaps, unless it's a block migration: */ + if (bdrv_dirty_bitmap_get_persistance(bitmap) && + !migrate_use_block()) { + continue; + } + if (drive_name =3D=3D NULL) { error_report("Found bitmap '%s' in unnamed node %p. It can= 't " "be migrated", bdrv_dirty_bitmap_name(bitmap)= , bs); @@ -335,11 +341,6 @@ static int init_dirty_bitmap_migration(void) } } =20 - /* unset persistance here, to not roll back it */ - QSIMPLEQ_FOREACH(dbms, &dirty_bitmap_mig_state.dbms_list, entry) { - bdrv_dirty_bitmap_set_persistance(dbms->bitmap, false); - } - if (QSIMPLEQ_EMPTY(&dirty_bitmap_mig_state.dbms_list)) { dirty_bitmap_mig_state.no_bitmaps =3D true; } --=20 2.14.4