From patchwork Thu Jan 10 12:01:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yury Kotov X-Patchwork-Id: 10755621 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 52B8A13BF for ; Thu, 10 Jan 2019 12:05:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 41B4220408 for ; Thu, 10 Jan 2019 12:05:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3546F292C2; Thu, 10 Jan 2019 12:05:41 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 44E9820408 for ; Thu, 10 Jan 2019 12:05:40 +0000 (UTC) Received: from localhost ([127.0.0.1]:52921 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghZ5f-0004dl-FI for patchwork-qemu-devel@patchwork.kernel.org; Thu, 10 Jan 2019 07:05:39 -0500 Received: from eggs.gnu.org ([209.51.188.92]:49451) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghZ1p-0001Fa-I1 for qemu-devel@nongnu.org; Thu, 10 Jan 2019 07:01:47 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ghZ1k-00005T-Uy for qemu-devel@nongnu.org; Thu, 10 Jan 2019 07:01:41 -0500 Received: from forwardcorp1o.cmail.yandex.net ([37.9.109.47]:48490) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ghZ1k-0008Sj-AB for qemu-devel@nongnu.org; Thu, 10 Jan 2019 07:01:36 -0500 Received: from mxbackcorp1g.mail.yandex.net (mxbackcorp1g.mail.yandex.net [IPv6:2a02:6b8:0:1402::301]) by forwardcorp1o.cmail.yandex.net (Yandex) with ESMTP id 89093216A4; Thu, 10 Jan 2019 15:01:29 +0300 (MSK) Received: from smtpcorp1j.mail.yandex.net (smtpcorp1j.mail.yandex.net [2a02:6b8:0:1619::137]) by mxbackcorp1g.mail.yandex.net (nwsmtp/Yandex) with ESMTP id 98J7RAFVgx-1TRiGr7p; Thu, 10 Jan 2019 15:01:29 +0300 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex-team.ru; s=default; t=1547121689; bh=53jqSK6+8ALofi9OqTD429HSosnRtdYKeWmtqXFsYT0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=DBhkgi1cDQh+pXzWBZiUx9uk3CjK2iDFLNh/OL63kHBNPBtRZ7clLM+DUnxSvUDXU MemLSsjhp7Rbj2s3evYyZEQYQzYktTKTkL/wNTxpkAxSHjeknrsrnOYx3+Y+GdiO7T JyD7peI9sTqfI8m/rgzueM38uVnQhflNhfJjweSg= Authentication-Results: mxbackcorp1g.mail.yandex.net; dkim=pass header.i=@yandex-team.ru Received: from dynamic-red.dhcp.yndx.net (dynamic-red.dhcp.yndx.net [2a02:6b8:0:40c:e1bb:a1a7:a235:d6b4]) by smtpcorp1j.mail.yandex.net (nwsmtp/Yandex) with ESMTPSA id v4PGSBu40N-1ThufcP8; Thu, 10 Jan 2019 15:01:29 +0300 (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (Client certificate not present) From: Yury Kotov To: qemu-devel@nongnu.org, Eduardo Habkost , Igor Mammedov , Paolo Bonzini , Peter Crosthwaite , Richard Henderson , Juan Quintela , "Dr. David Alan Gilbert" , Eric Blake , Markus Armbruster , Thomas Huth , Laurent Vivier Date: Thu, 10 Jan 2019 15:01:19 +0300 Message-Id: <20190110120120.9943-4-yury-kotov@yandex-team.ru> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190110120120.9943-1-yury-kotov@yandex-team.ru> References: <20190110120120.9943-1-yury-kotov@yandex-team.ru> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 37.9.109.47 Subject: [Qemu-devel] [PATCH 3/4] migration: introduce ignore-external capability 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: wrfsh@yandex-team.ru Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP We want to use local migration to update QEMU for running guests. In this case we don't need to migrate external RAM. So, add a capability to ignore such blocks during live migration. Signed-off-by: Yury Kotov --- exec.c | 5 +++++ include/exec/cpu-common.h | 1 + migration/migration.c | 9 +++++++++ migration/migration.h | 1 + migration/ram.c | 37 ++++++++++++++++++++++++++++++++++--- qapi/migration.json | 6 +++++- 6 files changed, 55 insertions(+), 4 deletions(-) diff --git a/exec.c b/exec.c index ef2f29d7cb..3c3e42993f 100644 --- a/exec.c +++ b/exec.c @@ -2000,6 +2000,11 @@ void qemu_ram_unset_migratable(RAMBlock *rb) rb->flags &= ~RAM_MIGRATABLE; } +bool qemu_ram_is_external(RAMBlock *rb) +{ + return rb->flags & RAM_EXTERNAL; +} + /* Called with iothread lock held. */ void qemu_ram_set_idstr(RAMBlock *new_block, const char *name, DeviceState *dev) { diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h index 2ad2d6d86b..57e84e5aa4 100644 --- a/include/exec/cpu-common.h +++ b/include/exec/cpu-common.h @@ -78,6 +78,7 @@ void qemu_ram_set_uf_zeroable(RAMBlock *rb); bool qemu_ram_is_migratable(RAMBlock *rb); void qemu_ram_set_migratable(RAMBlock *rb); void qemu_ram_unset_migratable(RAMBlock *rb); +bool qemu_ram_is_external(RAMBlock *rb); size_t qemu_ram_pagesize(RAMBlock *block); size_t qemu_ram_pagesize_largest(void); diff --git a/migration/migration.c b/migration/migration.c index ffc4d9e556..9b789d3535 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -1979,6 +1979,15 @@ bool migrate_dirty_bitmaps(void) return s->enabled_capabilities[MIGRATION_CAPABILITY_DIRTY_BITMAPS]; } +bool migrate_ignore_external(void) +{ + MigrationState *s; + + s = migrate_get_current(); + + return s->enabled_capabilities[MIGRATION_CAPABILITY_X_IGNORE_EXTERNAL]; +} + bool migrate_use_events(void) { MigrationState *s; diff --git a/migration/migration.h b/migration/migration.h index e413d4d8b6..06691242f3 100644 --- a/migration/migration.h +++ b/migration/migration.h @@ -255,6 +255,7 @@ bool migrate_release_ram(void); bool migrate_postcopy_ram(void); bool migrate_zero_blocks(void); bool migrate_dirty_bitmaps(void); +bool migrate_ignore_external(void); bool migrate_auto_converge(void); bool migrate_use_multifd(void); diff --git a/migration/ram.c b/migration/ram.c index 39629254e1..0091a8ae3a 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -166,6 +166,11 @@ out: #undef RAMBLOCK_FOREACH +static bool is_ignored_block(RAMBlock *block) +{ + return migrate_ignore_external() && qemu_ram_is_external(block); +} + static void ramblock_recv_map_init(void) { RAMBlock *rb; @@ -1537,7 +1542,7 @@ unsigned long migration_bitmap_find_dirty(RAMState *rs, RAMBlock *rb, unsigned long *bitmap = rb->bmap; unsigned long next; - if (!qemu_ram_is_migratable(rb)) { + if (!qemu_ram_is_migratable(rb) || is_ignored_block(rb)) { return size; } @@ -1651,6 +1656,9 @@ static void migration_bitmap_sync(RAMState *rs) qemu_mutex_lock(&rs->bitmap_mutex); rcu_read_lock(); RAMBLOCK_FOREACH_MIGRATABLE(block) { + if (is_ignored_block(block)) { + continue; + } migration_bitmap_sync_range(rs, block, 0, block->used_length); } ram_counters.remaining = ram_bytes_remaining(); @@ -2472,19 +2480,27 @@ void acct_update_position(QEMUFile *f, size_t size, bool zero) } } -uint64_t ram_bytes_total(void) +static uint64_t ram_bytes_total_common(bool skip_ignored) { RAMBlock *block; uint64_t total = 0; rcu_read_lock(); RAMBLOCK_FOREACH_MIGRATABLE(block) { + if (skip_ignored && is_ignored_block(block)) { + continue; + } total += block->used_length; } rcu_read_unlock(); return total; } +uint64_t ram_bytes_total(void) +{ + return ram_bytes_total_common(true); +} + static void xbzrle_load_setup(void) { XBZRLE.decoded_buf = g_malloc(TARGET_PAGE_SIZE); @@ -3162,7 +3178,7 @@ static int ram_save_setup(QEMUFile *f, void *opaque) rcu_read_lock(); - qemu_put_be64(f, ram_bytes_total() | RAM_SAVE_FLAG_MEM_SIZE); + qemu_put_be64(f, ram_bytes_total_common(false) | RAM_SAVE_FLAG_MEM_SIZE); RAMBLOCK_FOREACH_MIGRATABLE(block) { qemu_put_byte(f, strlen(block->idstr)); @@ -3172,6 +3188,7 @@ static int ram_save_setup(QEMUFile *f, void *opaque) qemu_put_be64(f, block->page_size); } qemu_put_be64(f, block->offset); + qemu_put_byte(f, is_ignored_block(block) ? 1 : 0); } rcu_read_unlock(); @@ -4135,13 +4152,27 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id) } if (version_id >= 5) { ram_addr_t offset; + bool ignored; offset = qemu_get_be64(f); + ignored = qemu_get_byte(f); if (block->offset != offset) { error_report("Mismatched RAM block offset %s " "%" PRId64 "!= %" PRId64, id, offset, (uint64_t)block->offset); ret = -EINVAL; } + if (ignored) { + if (!migrate_ignore_external()) { + error_report("Unexpected ignored RAM block %s: " + "ignore-external capability is " + "disabled", id); + ret = -EINVAL; + } else if (!qemu_ram_is_external(block)) { + error_report("Only external RAM block %s " + "can be ignored", id); + ret = -EINVAL; + } + } } ram_control_load_hook(f, RAM_CONTROL_BLOCK_REG, block->idstr); diff --git a/qapi/migration.json b/qapi/migration.json index 31b589ec26..10bbac87f8 100644 --- a/qapi/migration.json +++ b/qapi/migration.json @@ -406,13 +406,17 @@ # devices (and thus take locks) immediately at the end of migration. # (since 3.0) # +# @x-ignore-external: If enabled, QEMU will not migrate shared memory +# (since 4.0) +# # Since: 1.2 ## { 'enum': 'MigrationCapability', 'data': ['xbzrle', 'rdma-pin-all', 'auto-converge', 'zero-blocks', 'compress', 'events', 'postcopy-ram', 'x-colo', 'release-ram', 'block', 'return-path', 'pause-before-switchover', 'x-multifd', - 'dirty-bitmaps', 'postcopy-blocktime', 'late-block-activate' ] } + 'dirty-bitmaps', 'postcopy-blocktime', 'late-block-activate', + 'x-ignore-external' ] } ## # @MigrationCapabilityStatus: