From nobody Sun Feb 8 11:59:21 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; 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=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1626859806082632.4458228447553; Wed, 21 Jul 2021 02:30:06 -0700 (PDT) Received: from localhost ([::1]:59588 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1m68YG-0002Mp-Vj for importer@patchew.org; Wed, 21 Jul 2021 05:30:05 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:41414) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m68WU-0008Cj-Ny for qemu-devel@nongnu.org; Wed, 21 Jul 2021 05:28:14 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:35122) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m68WT-00026A-63 for qemu-devel@nongnu.org; Wed, 21 Jul 2021 05:28:14 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-265-5PFOg5tENcCbRt9wb-G85w-1; Wed, 21 Jul 2021 05:28:09 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id EF76DCC644; Wed, 21 Jul 2021 09:28:07 +0000 (UTC) Received: from t480s.redhat.com (ovpn-113-250.ams2.redhat.com [10.36.113.250]) by smtp.corp.redhat.com (Postfix) with ESMTP id A78356A056; Wed, 21 Jul 2021 09:28:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1626859692; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=R5CSxdLKPB6pQr4rD1BZDpeO+5Cn5HeY3iUktPCWG70=; b=Bc1cIUZ30UiAAiblPsg3AJrZG4GsjJmcms6g8ce+idtAjbT8RaMc74uAUFoB5d3Tf2UROH qXq4zmdicwIBXDJzCW8iSWSVAiju+L6HMLWQ/ovAiJwIra89zONFStKCjKUJTaAyi6B/5z YRBoDgQnh4gMTosoNJ1/yXmm5hNvzE0= X-MC-Unique: 5PFOg5tENcCbRt9wb-G85w-1 From: David Hildenbrand To: qemu-devel@nongnu.org Subject: [PATCH v2 1/6] memory: Introduce replay_discarded callback for RamDiscardManager Date: Wed, 21 Jul 2021 11:27:54 +0200 Message-Id: <20210721092759.21368-2-david@redhat.com> In-Reply-To: <20210721092759.21368-1-david@redhat.com> References: <20210721092759.21368-1-david@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=david@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable 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=216.205.24.124; envelope-from=david@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -42 X-Spam_score: -4.3 X-Spam_bar: ---- X-Spam_report: (-4.3 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.474, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eduardo Habkost , "Michael S. Tsirkin" , Pankaj Gupta , Juan Quintela , David Hildenbrand , "Dr. David Alan Gilbert" , Peter Xu , Marek Kedzierski , Alex Williamson , teawater , Paolo Bonzini , Andrey Gruzdev , Wei Yang Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1626859807493100001 Content-Type: text/plain; charset="utf-8" Introduce replay_discarded callback similar to our existing replay_populated callback, to be used my migration code to never migrate discarded memory. Signed-off-by: David Hildenbrand Acked-by: Peter Xu --- include/exec/memory.h | 21 +++++++++++++++++++++ softmmu/memory.c | 11 +++++++++++ 2 files changed, 32 insertions(+) diff --git a/include/exec/memory.h b/include/exec/memory.h index c3d417d317..93e972b55a 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -537,6 +537,7 @@ static inline void ram_discard_listener_init(RamDiscard= Listener *rdl, } =20 typedef int (*ReplayRamPopulate)(MemoryRegionSection *section, void *opaqu= e); +typedef void (*ReplayRamDiscard)(MemoryRegionSection *section, void *opaqu= e); =20 /* * RamDiscardManagerClass: @@ -625,6 +626,21 @@ struct RamDiscardManagerClass { MemoryRegionSection *section, ReplayRamPopulate replay_fn, void *opaque); =20 + /** + * @replay_discarded: + * + * Call the #ReplayRamDiscard callback for all discarded parts within = the + * #MemoryRegionSection via the #RamDiscardManager. + * + * @rdm: the #RamDiscardManager + * @section: the #MemoryRegionSection + * @replay_fn: the #ReplayRamDiscard callback + * @opaque: pointer to forward to the callback + */ + void (*replay_discarded)(const RamDiscardManager *rdm, + MemoryRegionSection *section, + ReplayRamDiscard replay_fn, void *opaque); + /** * @register_listener: * @@ -669,6 +685,11 @@ int ram_discard_manager_replay_populated(const RamDisc= ardManager *rdm, ReplayRamPopulate replay_fn, void *opaque); =20 +void ram_discard_manager_replay_discarded(const RamDiscardManager *rdm, + MemoryRegionSection *section, + ReplayRamDiscard replay_fn, + void *opaque); + void ram_discard_manager_register_listener(RamDiscardManager *rdm, RamDiscardListener *rdl, MemoryRegionSection *section); diff --git a/softmmu/memory.c b/softmmu/memory.c index bfedaf9c4d..cd86205627 100644 --- a/softmmu/memory.c +++ b/softmmu/memory.c @@ -2076,6 +2076,17 @@ int ram_discard_manager_replay_populated(const RamDi= scardManager *rdm, return rdmc->replay_populated(rdm, section, replay_fn, opaque); } =20 +void ram_discard_manager_replay_discarded(const RamDiscardManager *rdm, + MemoryRegionSection *section, + ReplayRamDiscard replay_fn, + void *opaque) +{ + RamDiscardManagerClass *rdmc =3D RAM_DISCARD_MANAGER_GET_CLASS(rdm); + + g_assert(rdmc->replay_discarded); + rdmc->replay_discarded(rdm, section, replay_fn, opaque); +} + void ram_discard_manager_register_listener(RamDiscardManager *rdm, RamDiscardListener *rdl, MemoryRegionSection *section) --=20 2.31.1 From nobody Sun Feb 8 11:59:21 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; 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=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1626860068238359.31624698270775; Wed, 21 Jul 2021 02:34:28 -0700 (PDT) Received: from localhost ([::1]:41876 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1m68cV-00015q-2n for importer@patchew.org; Wed, 21 Jul 2021 05:34:27 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:41424) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m68WV-0008DR-RD for qemu-devel@nongnu.org; Wed, 21 Jul 2021 05:28:16 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:56321) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m68WU-00027k-BQ for qemu-devel@nongnu.org; Wed, 21 Jul 2021 05:28:15 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-389-DgcBOfm3NBq99pBLLxoEjQ-1; Wed, 21 Jul 2021 05:28:12 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 57C3E800D62; Wed, 21 Jul 2021 09:28:11 +0000 (UTC) Received: from t480s.redhat.com (ovpn-113-250.ams2.redhat.com [10.36.113.250]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4FC09687D5; Wed, 21 Jul 2021 09:28:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1626859693; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=xrmG1HrC49Xsw2bKc5rtD1Gkuqb3l6Hoh0HmzH5/zYs=; b=WvJgLDcQLNEifMVuZBUnPV9NLVZCJLOJWNv4RKwKvb/+liAiaeNZo9p+GAX2G2XXJ9qqD7 i+rZnuQ5GuybUyvezUuRVrbsIbDAW9n+rk6JB5azadPJoqV8Jlzp+g623dfU1Mgus5g+i7 BgEMREgxtZozOGY0FswKbsvACwVFgUM= X-MC-Unique: DgcBOfm3NBq99pBLLxoEjQ-1 From: David Hildenbrand To: qemu-devel@nongnu.org Subject: [PATCH v2 2/6] virtio-mem: Implement replay_discarded RamDiscardManager callback Date: Wed, 21 Jul 2021 11:27:55 +0200 Message-Id: <20210721092759.21368-3-david@redhat.com> In-Reply-To: <20210721092759.21368-1-david@redhat.com> References: <20210721092759.21368-1-david@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=david@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable 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=216.205.24.124; envelope-from=david@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -42 X-Spam_score: -4.3 X-Spam_bar: ---- X-Spam_report: (-4.3 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.474, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eduardo Habkost , "Michael S. Tsirkin" , Pankaj Gupta , Juan Quintela , David Hildenbrand , "Dr. David Alan Gilbert" , Peter Xu , Marek Kedzierski , Alex Williamson , teawater , Paolo Bonzini , Andrey Gruzdev , Wei Yang Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1626860068611100001 Content-Type: text/plain; charset="utf-8" Implement it similar to the replay_populated callback. Signed-off-by: David Hildenbrand Acked-by: Peter Xu --- hw/virtio/virtio-mem.c | 58 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c index df91e454b2..284096ec5f 100644 --- a/hw/virtio/virtio-mem.c +++ b/hw/virtio/virtio-mem.c @@ -228,6 +228,38 @@ static int virtio_mem_for_each_plugged_section(const V= irtIOMEM *vmem, return ret; } =20 +static int virtio_mem_for_each_unplugged_section(const VirtIOMEM *vmem, + MemoryRegionSection *s, + void *arg, + virtio_mem_section_cb cb) +{ + unsigned long first_bit, last_bit; + uint64_t offset, size; + int ret =3D 0; + + first_bit =3D s->offset_within_region / vmem->bitmap_size; + first_bit =3D find_next_zero_bit(vmem->bitmap, vmem->bitmap_size, firs= t_bit); + while (first_bit < vmem->bitmap_size) { + MemoryRegionSection tmp =3D *s; + + offset =3D first_bit * vmem->block_size; + last_bit =3D find_next_bit(vmem->bitmap, vmem->bitmap_size, + first_bit + 1) - 1; + size =3D (last_bit - first_bit + 1) * vmem->block_size; + + if (!virito_mem_intersect_memory_section(&tmp, offset, size)) { + break; + } + ret =3D cb(&tmp, arg); + if (ret) { + break; + } + first_bit =3D find_next_zero_bit(vmem->bitmap, vmem->bitmap_size, + last_bit + 2); + } + return ret; +} + static int virtio_mem_notify_populate_cb(MemoryRegionSection *s, void *arg) { RamDiscardListener *rdl =3D arg; @@ -1170,6 +1202,31 @@ static int virtio_mem_rdm_replay_populated(const Ram= DiscardManager *rdm, virtio_mem_rdm_replay_populate= d_cb); } =20 +static int virtio_mem_rdm_replay_discarded_cb(MemoryRegionSection *s, + void *arg) +{ + struct VirtIOMEMReplayData *data =3D arg; + + ((ReplayRamDiscard)data->fn)(s, data->opaque); + return 0; +} + +static void virtio_mem_rdm_replay_discarded(const RamDiscardManager *rdm, + MemoryRegionSection *s, + ReplayRamDiscard replay_fn, + void *opaque) +{ + const VirtIOMEM *vmem =3D VIRTIO_MEM(rdm); + struct VirtIOMEMReplayData data =3D { + .fn =3D replay_fn, + .opaque =3D opaque, + }; + + g_assert(s->mr =3D=3D &vmem->memdev->mr); + virtio_mem_for_each_unplugged_section(vmem, s, &data, + virtio_mem_rdm_replay_discarded_= cb); +} + static void virtio_mem_rdm_register_listener(RamDiscardManager *rdm, RamDiscardListener *rdl, MemoryRegionSection *s) @@ -1234,6 +1291,7 @@ static void virtio_mem_class_init(ObjectClass *klass,= void *data) rdmc->get_min_granularity =3D virtio_mem_rdm_get_min_granularity; rdmc->is_populated =3D virtio_mem_rdm_is_populated; rdmc->replay_populated =3D virtio_mem_rdm_replay_populated; + rdmc->replay_discarded =3D virtio_mem_rdm_replay_discarded; rdmc->register_listener =3D virtio_mem_rdm_register_listener; rdmc->unregister_listener =3D virtio_mem_rdm_unregister_listener; } --=20 2.31.1 From nobody Sun Feb 8 11:59:21 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; 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=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1626859834233406.212919076875; Wed, 21 Jul 2021 02:30:34 -0700 (PDT) Received: from localhost ([::1]:59892 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1m68Yi-0002Yn-EG for importer@patchew.org; Wed, 21 Jul 2021 05:30:32 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:41436) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m68Wb-0008IW-K0 for qemu-devel@nongnu.org; Wed, 21 Jul 2021 05:28:21 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:39142) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m68WZ-0002Ar-P2 for qemu-devel@nongnu.org; Wed, 21 Jul 2021 05:28:21 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-90-CdjywrObPpCykgabKcs16Q-1; Wed, 21 Jul 2021 05:28:15 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id AAB7E839A4A; Wed, 21 Jul 2021 09:28:14 +0000 (UTC) Received: from t480s.redhat.com (ovpn-113-250.ams2.redhat.com [10.36.113.250]) by smtp.corp.redhat.com (Postfix) with ESMTP id B739F6A057; Wed, 21 Jul 2021 09:28:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1626859698; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=dn43e+TJIOkgVC/LZmxDiQvAKcUzmdGHniwvhvKtycQ=; b=Zf7TyRBNXCtkWi462posaGFYAxwA4PehmCMUutP2Q/vYbjA1ZeCQCnBnxH4lvYy4rImkHY Hi7n9twxSaDYrHFkbmqiIIb+Tk0W3fpRulkf0cW7QAClHpt9v4afeXlWiEWoEFXW5XIJGx aRJRfomFcQ+c34p6SCiaEUGDy+PkN0g= X-MC-Unique: CdjywrObPpCykgabKcs16Q-1 From: David Hildenbrand To: qemu-devel@nongnu.org Subject: [PATCH v2 3/6] migration/ram: Handle RAMBlocks with a RamDiscardManager on the migration source Date: Wed, 21 Jul 2021 11:27:56 +0200 Message-Id: <20210721092759.21368-4-david@redhat.com> In-Reply-To: <20210721092759.21368-1-david@redhat.com> References: <20210721092759.21368-1-david@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=david@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable 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=david@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -42 X-Spam_score: -4.3 X-Spam_bar: ---- X-Spam_report: (-4.3 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.474, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eduardo Habkost , "Michael S. Tsirkin" , Pankaj Gupta , Juan Quintela , David Hildenbrand , "Dr. David Alan Gilbert" , Peter Xu , Marek Kedzierski , Alex Williamson , teawater , Paolo Bonzini , Andrey Gruzdev , Wei Yang Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1626859836139100001 Content-Type: text/plain; charset="utf-8" We never want to migrate memory that corresponds to discarded ranges as managed by a RamDiscardManager responsible for the mapped memory region of the RAMBlock. The content of these pages is essentially stale and without any guarantees for the VM ("logically unplugged"). Depending on the underlying memory type, even reading memory might populate memory on the source, resulting in an undesired memory consumption. Of course, on the destination, even writing a zeropage consumes memory, which we also want to avoid (similar to free page hinting). Currently, virtio-mem tries achieving that goal (not migrating "unplugged" memory that was discarded) by going via qemu_guest_free_page_hint() - but it's hackish and incomplete. For example, background snapshots still end up reading all memory, as they don't do bitmap syncs. Postcopy recovery code will re-add previously cleared bits to the dirty bitmap and migrate them. Let's consult the RamDiscardManager whenever we add bits to the bitmap and exclude all discarded pages. As colo is incompatible with discarding of RAM and inhibits it, we don't have to bother. Note: If discarded ranges span complete clear_bmap chunks, we'll never clear the corresponding bits from clear_bmap and consequently never call memory_region_clear_dirty_bitmap on the affected regions. While this is perfectly fine, we're still synchronizing the bitmap of discarded ranges, for example, in ramblock_sync_dirty_bitmap()->cpu_physical_memory_sync_dirty_bitmap() but also during memory_global_dirty_log_sync(). In the future, it might make sense to never even synchronize the dirty log of these ranges, for example in KVM code, skipping discarded ranges completely. Signed-off-by: David Hildenbrand --- migration/ram.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 65 insertions(+), 4 deletions(-) diff --git a/migration/ram.c b/migration/ram.c index b5fc454b2f..4bf74ae2e1 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -830,14 +830,67 @@ static inline bool migration_bitmap_clear_dirty(RAMSt= ate *rs, return ret; } =20 +static void dirty_bitmap_exclude_section(MemoryRegionSection *section, + void *opaque) +{ + const hwaddr offset =3D section->offset_within_region; + const hwaddr size =3D int128_get64(section->size); + const unsigned long start =3D offset >> TARGET_PAGE_BITS; + const unsigned long npages =3D size >> TARGET_PAGE_BITS; + RAMBlock *rb =3D section->mr->ram_block; + uint64_t *cleared_bits =3D opaque; + + /* Clear the discarded part from our bitmap. */ + *cleared_bits +=3D bitmap_count_one_with_offset(rb->bmap, start, npage= s); + bitmap_clear(rb->bmap, start, npages); +} + +/* + * Exclude all dirty pages that fall into a discarded range as managed by a + * RamDiscardManager responsible for the mapped memory region of the RAMBl= ock. + * + * Discarded pages ("logically unplugged") have undefined content and must + * never be migrated, because even reading these pages for migrating might + * result in undesired behavior. + * + * Returns the number of cleared bits in the dirty bitmap. + * + * Note: The result is only stable while migration (precopy/postcopy). + */ +static uint64_t ramblock_dirty_bitmap_exclude_discarded_pages(RAMBlock *rb) +{ + uint64_t cleared_bits =3D 0; + + if (rb->mr && memory_region_has_ram_discard_manager(rb->mr)) { + RamDiscardManager *rdm =3D memory_region_get_ram_discard_manager(r= b->mr); + MemoryRegionSection section =3D { + .mr =3D rb->mr, + .offset_within_region =3D 0, + .size =3D int128_make64(qemu_ram_get_used_length(rb)), + }; + + ram_discard_manager_replay_discarded(rdm, §ion, + dirty_bitmap_exclude_section, + &cleared_bits); + } + return cleared_bits; +} + /* Called with RCU critical section */ static void ramblock_sync_dirty_bitmap(RAMState *rs, RAMBlock *rb) { uint64_t new_dirty_pages =3D cpu_physical_memory_sync_dirty_bitmap(rb, 0, rb->used_length); + uint64_t cleared_pages =3D 0; =20 - rs->migration_dirty_pages +=3D new_dirty_pages; - rs->num_dirty_pages_period +=3D new_dirty_pages; + if (new_dirty_pages) { + cleared_pages =3D ramblock_dirty_bitmap_exclude_discarded_pages(rb= ); + } + + rs->migration_dirty_pages +=3D new_dirty_pages - cleared_pages; + if (new_dirty_pages > cleared_pages) { + rs->num_dirty_pages_period +=3D new_dirty_pages - cleared_pages; + } } =20 /** @@ -2601,7 +2654,7 @@ static int ram_state_init(RAMState **rsp) return 0; } =20 -static void ram_list_init_bitmaps(void) +static void ram_list_init_bitmaps(RAMState *rs) { MigrationState *ms =3D migrate_get_current(); RAMBlock *block; @@ -2636,6 +2689,10 @@ static void ram_list_init_bitmaps(void) bitmap_set(block->bmap, 0, pages); block->clear_bmap_shift =3D shift; block->clear_bmap =3D bitmap_new(clear_bmap_size(pages, shift)= ); + + /* Exclude all discarded pages we never want to migrate. */ + pages =3D ramblock_dirty_bitmap_exclude_discarded_pages(block); + rs->migration_dirty_pages -=3D pages; } } } @@ -2647,7 +2704,7 @@ static void ram_init_bitmaps(RAMState *rs) qemu_mutex_lock_ramlist(); =20 WITH_RCU_READ_LOCK_GUARD() { - ram_list_init_bitmaps(); + ram_list_init_bitmaps(rs); /* We don't use dirty log with background snapshots */ if (!migrate_background_snapshot()) { memory_global_dirty_log_start(); @@ -4076,6 +4133,10 @@ int ram_dirty_bitmap_reload(MigrationState *s, RAMBl= ock *block) */ bitmap_complement(block->bmap, block->bmap, nbits); =20 + /* Exclude all discarded pages we never want to migrate. */ + ramblock_dirty_bitmap_exclude_discarded_pages(block); + + /* We'll recalculate migration_dirty_pages in ram_state_resume_prepare= (). */ trace_ram_dirty_bitmap_reload_complete(block->idstr); =20 /* --=20 2.31.1 From nobody Sun Feb 8 11:59:21 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; 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=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 162686000355357.710299300026804; Wed, 21 Jul 2021 02:33:23 -0700 (PDT) Received: from localhost ([::1]:39042 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1m68bR-0007cV-Kt for importer@patchew.org; Wed, 21 Jul 2021 05:33:21 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:41462) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m68We-0008MY-TR for qemu-devel@nongnu.org; Wed, 21 Jul 2021 05:28:25 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:37484) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m68Wc-0002CH-A9 for qemu-devel@nongnu.org; Wed, 21 Jul 2021 05:28:24 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-431-QEwmBUA2M4mSH7aUc73FkQ-1; Wed, 21 Jul 2021 05:28:19 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 37F07100A643; Wed, 21 Jul 2021 09:28:18 +0000 (UTC) Received: from t480s.redhat.com (ovpn-113-250.ams2.redhat.com [10.36.113.250]) by smtp.corp.redhat.com (Postfix) with ESMTP id F197C687D5; Wed, 21 Jul 2021 09:28:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1626859701; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=cugHBsF3qxGH5mEV4jWCO8prxN3ZaEMd6ARj8tgl4Lg=; b=Gl1yqa+diMvHKqodkGsWdOj6WDKM2/wG5Ee1pUVMSuh0n/KJuCZeZUCPr2JY5bomMgU1xn 7eS7qnns8Jl+uuLfHCIRrAeq+l+qwKCAB4RYvxZO8NdczrcjiIRwPUsgrGxbTpJAoDn0FT Qw30rgP0oZByU/RVhIsep7XT244Czco= X-MC-Unique: QEwmBUA2M4mSH7aUc73FkQ-1 From: David Hildenbrand To: qemu-devel@nongnu.org Subject: [PATCH v2 4/6] virtio-mem: Drop precopy notifier Date: Wed, 21 Jul 2021 11:27:57 +0200 Message-Id: <20210721092759.21368-5-david@redhat.com> In-Reply-To: <20210721092759.21368-1-david@redhat.com> References: <20210721092759.21368-1-david@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=david@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable 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=216.205.24.124; envelope-from=david@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -42 X-Spam_score: -4.3 X-Spam_bar: ---- X-Spam_report: (-4.3 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.474, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eduardo Habkost , "Michael S. Tsirkin" , Pankaj Gupta , Juan Quintela , David Hildenbrand , "Dr. David Alan Gilbert" , Peter Xu , Marek Kedzierski , Alex Williamson , teawater , Paolo Bonzini , Andrey Gruzdev , Wei Yang Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1626860004388100001 Content-Type: text/plain; charset="utf-8" Migration code now properly handles RAMBlocks which are indirectly managed by a RamDiscardManager. No need for manual handling via the free page optimization interface, let's get rid of it. Acked-by: Michael S. Tsirkin Signed-off-by: David Hildenbrand Acked-by: Peter Xu --- hw/virtio/virtio-mem.c | 34 ---------------------------------- include/hw/virtio/virtio-mem.h | 3 --- 2 files changed, 37 deletions(-) diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c index 284096ec5f..d5a578142b 100644 --- a/hw/virtio/virtio-mem.c +++ b/hw/virtio/virtio-mem.c @@ -776,7 +776,6 @@ static void virtio_mem_device_realize(DeviceState *dev,= Error **errp) host_memory_backend_set_mapped(vmem->memdev, true); vmstate_register_ram(&vmem->memdev->mr, DEVICE(vmem)); qemu_register_reset(virtio_mem_system_reset, vmem); - precopy_add_notifier(&vmem->precopy_notifier); =20 /* * Set ourselves as RamDiscardManager before the plug handler maps the @@ -796,7 +795,6 @@ static void virtio_mem_device_unrealize(DeviceState *de= v) * found via an address space anymore. Unset ourselves. */ memory_region_set_ram_discard_manager(&vmem->memdev->mr, NULL); - precopy_remove_notifier(&vmem->precopy_notifier); qemu_unregister_reset(virtio_mem_system_reset, vmem); vmstate_unregister_ram(&vmem->memdev->mr, DEVICE(vmem)); host_memory_backend_set_mapped(vmem->memdev, false); @@ -1089,43 +1087,11 @@ static void virtio_mem_set_block_size(Object *obj, = Visitor *v, const char *name, vmem->block_size =3D value; } =20 -static int virtio_mem_precopy_exclude_range_cb(const VirtIOMEM *vmem, void= *arg, - uint64_t offset, uint64_t s= ize) -{ - void * const host =3D qemu_ram_get_host_addr(vmem->memdev->mr.ram_bloc= k); - - qemu_guest_free_page_hint(host + offset, size); - return 0; -} - -static void virtio_mem_precopy_exclude_unplugged(VirtIOMEM *vmem) -{ - virtio_mem_for_each_unplugged_range(vmem, NULL, - virtio_mem_precopy_exclude_range_c= b); -} - -static int virtio_mem_precopy_notify(NotifierWithReturn *n, void *data) -{ - VirtIOMEM *vmem =3D container_of(n, VirtIOMEM, precopy_notifier); - PrecopyNotifyData *pnd =3D data; - - switch (pnd->reason) { - case PRECOPY_NOTIFY_AFTER_BITMAP_SYNC: - virtio_mem_precopy_exclude_unplugged(vmem); - break; - default: - break; - } - - return 0; -} - static void virtio_mem_instance_init(Object *obj) { VirtIOMEM *vmem =3D VIRTIO_MEM(obj); =20 notifier_list_init(&vmem->size_change_notifiers); - vmem->precopy_notifier.notify =3D virtio_mem_precopy_notify; QLIST_INIT(&vmem->rdl_list); =20 object_property_add(obj, VIRTIO_MEM_SIZE_PROP, "size", virtio_mem_get_= size, diff --git a/include/hw/virtio/virtio-mem.h b/include/hw/virtio/virtio-mem.h index 9a6e348fa2..a5dd6a493b 100644 --- a/include/hw/virtio/virtio-mem.h +++ b/include/hw/virtio/virtio-mem.h @@ -65,9 +65,6 @@ struct VirtIOMEM { /* notifiers to notify when "size" changes */ NotifierList size_change_notifiers; =20 - /* don't migrate unplugged memory */ - NotifierWithReturn precopy_notifier; - /* listeners to notify on plug/unplug activity. */ QLIST_HEAD(, RamDiscardListener) rdl_list; }; --=20 2.31.1 From nobody Sun Feb 8 11:59:21 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; 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=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1626859852222445.33380103612285; Wed, 21 Jul 2021 02:30:52 -0700 (PDT) Received: from localhost ([::1]:59954 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1m68Z1-0002bJ-2c for importer@patchew.org; Wed, 21 Jul 2021 05:30:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:41472) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m68Wg-0008Nw-4N for qemu-devel@nongnu.org; Wed, 21 Jul 2021 05:28:26 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:50498) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m68We-0002Dl-Da for qemu-devel@nongnu.org; Wed, 21 Jul 2021 05:28:25 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-108-y3MmmFhgPC6nhfw2WESYhA-1; Wed, 21 Jul 2021 05:28:22 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 936AC1009E49; Wed, 21 Jul 2021 09:28:21 +0000 (UTC) Received: from t480s.redhat.com (ovpn-113-250.ams2.redhat.com [10.36.113.250]) by smtp.corp.redhat.com (Postfix) with ESMTP id 673356A056; Wed, 21 Jul 2021 09:28:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1626859703; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=uAuJR0xfWOQm+EkBs7DCBiF5SEs1lqhgIDtBamV9pus=; b=UEptIOhXmKxNRrh2ximqXPAXCw0z3x+i+cdN+jO7TaBO4Hi34xgHvu47AMZrZJ3J9O8ssX yXd138466Y4vWP4B+ru3Ido5X8J8AXO/AFQyqO/HHYFxdNQUlPIvQyRysV0NoC6HlcIzuF xZecMddhKyQL+EqFSg5qwGj13nMuZFg= X-MC-Unique: y3MmmFhgPC6nhfw2WESYhA-1 From: David Hildenbrand To: qemu-devel@nongnu.org Subject: [PATCH v2 5/6] migration/postcopy: Handle RAMBlocks with a RamDiscardManager on the destination Date: Wed, 21 Jul 2021 11:27:58 +0200 Message-Id: <20210721092759.21368-6-david@redhat.com> In-Reply-To: <20210721092759.21368-1-david@redhat.com> References: <20210721092759.21368-1-david@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=david@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable 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=david@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -42 X-Spam_score: -4.3 X-Spam_bar: ---- X-Spam_report: (-4.3 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.474, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eduardo Habkost , "Michael S. Tsirkin" , Pankaj Gupta , Juan Quintela , David Hildenbrand , "Dr. David Alan Gilbert" , Peter Xu , Marek Kedzierski , Alex Williamson , teawater , Paolo Bonzini , Andrey Gruzdev , Wei Yang Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1626859853076100001 Content-Type: text/plain; charset="utf-8" Currently, when someone (i.e., the VM) accesses discarded parts inside a RAMBlock with a RamDiscardManager managing the corresponding mapped memory region, postcopy will request migration of the corresponding page from the source. The source, however, will never answer, because it refuses to migrate such pages with undefined content ("logically unplugged"): the pages are never dirty, and get_queued_page() will consequently skip processing these postcopy requests. Especially reading discarded ("logically unplugged") ranges is supposed to work in some setups (for example with current virtio-mem), although it barely ever happens: still, not placing a page would currently stall the VM, as it cannot make forward progress. Let's check the state via the RamDiscardManager (the state e.g., of virtio-mem is migrated during precopy) and avoid sending a request that will never get answered. Place a fresh zero page instead to keep the VM working. This is the same behavior that would happen automatically without userfaultfd being active, when accessing virtual memory regions without populated pages -- "populate on demand". Signed-off-by: David Hildenbrand Reviewed-by: Peter Xu --- migration/postcopy-ram.c | 25 +++++++++++++++++++++---- migration/ram.c | 23 +++++++++++++++++++++++ migration/ram.h | 1 + 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c index 2e9697bdd2..673f60ce2b 100644 --- a/migration/postcopy-ram.c +++ b/migration/postcopy-ram.c @@ -671,6 +671,23 @@ int postcopy_wake_shared(struct PostCopyFD *pcfd, return ret; } =20 +static int postcopy_request_page(MigrationIncomingState *mis, RAMBlock *rb, + ram_addr_t start, uint64_t haddr) +{ + /* + * Discarded pages (via RamDiscardManager) are never migrated. On unli= kely + * access, place a zeropage, which will also set the relevant bits in = the + * recv_bitmap accordingly, so we won't try placing a zeropage twice. + */ + if (ramblock_page_is_discarded(rb, start)) { + bool received =3D ramblock_recv_bitmap_test_byte_offset(rb, start); + + return received ? 0 : postcopy_place_page_zero(mis, (void *)haddr,= rb); + } + + return migrate_send_rp_req_pages(mis, rb, start, haddr); +} + /* * Callback from shared fault handlers to ask for a page, * the page must be specified by a RAMBlock and an offset in that rb @@ -690,7 +707,7 @@ int postcopy_request_shared_page(struct PostCopyFD *pcf= d, RAMBlock *rb, qemu_ram_get_idstr(rb), rb_offset); return postcopy_wake_shared(pcfd, client_addr, rb); } - migrate_send_rp_req_pages(mis, rb, aligned_rbo, client_addr); + postcopy_request_page(mis, rb, aligned_rbo, client_addr); return 0; } =20 @@ -984,8 +1001,8 @@ retry: * Send the request to the source - we want to request one * of our host page sizes (which is >=3D TPS) */ - ret =3D migrate_send_rp_req_pages(mis, rb, rb_offset, - msg.arg.pagefault.address); + ret =3D postcopy_request_page(mis, rb, rb_offset, + msg.arg.pagefault.address); if (ret) { /* May be network failure, try to wait for recovery */ if (ret =3D=3D -EIO && postcopy_pause_fault_thread(mis)) { @@ -993,7 +1010,7 @@ retry: goto retry; } else { /* This is a unavoidable fault */ - error_report("%s: migrate_send_rp_req_pages() get %d", + error_report("%s: postcopy_request_page() get %d", __func__, ret); break; } diff --git a/migration/ram.c b/migration/ram.c index 4bf74ae2e1..d7505f5368 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -876,6 +876,29 @@ static uint64_t ramblock_dirty_bitmap_exclude_discarde= d_pages(RAMBlock *rb) return cleared_bits; } =20 +/* + * Check if a page falls into a discarded range as managed by a + * RamDiscardManager responsible for the mapped memory region of the RAMBl= ock. + * Pages inside discarded ranges are never migrated and postcopy has to + * place zeropages instead. + * + * Note: The result is only stable while migration (precopy/postcopy). + */ +bool ramblock_page_is_discarded(RAMBlock *rb, ram_addr_t offset) +{ + if (rb->mr && memory_region_has_ram_discard_manager(rb->mr)) { + RamDiscardManager *rdm =3D memory_region_get_ram_discard_manager(r= b->mr); + MemoryRegionSection section =3D { + .mr =3D rb->mr, + .offset_within_region =3D offset, + .size =3D int128_get64(TARGET_PAGE_SIZE), + }; + + return !ram_discard_manager_is_populated(rdm, §ion); + } + return false; +} + /* Called with RCU critical section */ static void ramblock_sync_dirty_bitmap(RAMState *rs, RAMBlock *rb) { diff --git a/migration/ram.h b/migration/ram.h index 4833e9fd5b..6e7f12e556 100644 --- a/migration/ram.h +++ b/migration/ram.h @@ -72,6 +72,7 @@ void ramblock_recv_bitmap_set_range(RAMBlock *rb, void *h= ost_addr, size_t nr); int64_t ramblock_recv_bitmap_send(QEMUFile *file, const char *block_name); int ram_dirty_bitmap_reload(MigrationState *s, RAMBlock *rb); +bool ramblock_page_is_discarded(RAMBlock *rb, ram_addr_t offset); =20 /* ram cache */ int colo_init_ram_cache(void); --=20 2.31.1 From nobody Sun Feb 8 11:59:21 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; 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=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1626860149474768.9104632948339; Wed, 21 Jul 2021 02:35:49 -0700 (PDT) Received: from localhost ([::1]:45856 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1m68do-0003kO-G1 for importer@patchew.org; Wed, 21 Jul 2021 05:35:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:41500) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m68Wm-0008QO-08 for qemu-devel@nongnu.org; Wed, 21 Jul 2021 05:28:32 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:21418) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m68Wi-0002GE-2K for qemu-devel@nongnu.org; Wed, 21 Jul 2021 05:28:30 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-37-5oKEpxroM12HfWropJc9Vg-1; Wed, 21 Jul 2021 05:28:26 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id F21C180259B; Wed, 21 Jul 2021 09:28:24 +0000 (UTC) Received: from t480s.redhat.com (ovpn-113-250.ams2.redhat.com [10.36.113.250]) by smtp.corp.redhat.com (Postfix) with ESMTP id F1D3F687D5; Wed, 21 Jul 2021 09:28:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1626859707; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=KDHE5WeCEv+6agq7D2mw+/Z52QQ9LvAe20WYe2wi8BE=; b=CruxgFBLaGHeagK2juYFmk0OgGGuKdRX++NzN8+vhvmTW+ThaC8vMEMuTMrZitrvYGEl3Y mfZX0Js79gGxuoo/C1LW63egQzMxAMq3gdn4zXtOxNn5PUuoiyPWlfTcoNbpwpU753Khem Wk4TDy+pzgM0+ina1OtJovOnWMcCHNs= X-MC-Unique: 5oKEpxroM12HfWropJc9Vg-1 From: David Hildenbrand To: qemu-devel@nongnu.org Subject: [PATCH v2 6/6] migration/ram: Handle RAMBlocks with a RamDiscardManager on background snapshots Date: Wed, 21 Jul 2021 11:27:59 +0200 Message-Id: <20210721092759.21368-7-david@redhat.com> In-Reply-To: <20210721092759.21368-1-david@redhat.com> References: <20210721092759.21368-1-david@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=david@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable 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=216.205.24.124; envelope-from=david@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -42 X-Spam_score: -4.3 X-Spam_bar: ---- X-Spam_report: (-4.3 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.474, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eduardo Habkost , "Michael S. Tsirkin" , Pankaj Gupta , Juan Quintela , David Hildenbrand , "Dr. David Alan Gilbert" , Peter Xu , Marek Kedzierski , Alex Williamson , teawater , Paolo Bonzini , Andrey Gruzdev , Wei Yang Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1626860150146100001 Content-Type: text/plain; charset="utf-8" We already don't ever migrate memory that corresponds to discarded ranges as managed by a RamDiscardManager responsible for the mapped memory region of the RAMBlock. virtio-mem uses this mechanism to logically unplug parts of a RAMBlock. Right now, we still populate zeropages for the whole usable part of the RAMBlock, which is undesired because: 1. Even populating the shared zeropage will result in memory getting consumed for page tables. 2. Memory backends without a shared zeropage (like hugetlbfs and shmem) will populate an actual, fresh page, resulting in an unintended memory consumption. Discarded ("logically unplugged") parts have to remain discarded. As these pages are never part of the migration stream, there is no need to track modifications via userfaultfd WP reliably for these parts. Further, any writes to these ranges by the VM are invalid and the behavior is undefined. Note that Linux only supports userfaultfd WP on private anonymous memory for now, which usually results in the shared zeropage getting populated. The issue will become more relevant once userfaultfd WP supports shmem and hugetlb. Signed-off-by: David Hildenbrand Acked-by: Peter Xu --- migration/ram.c | 53 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/migration/ram.c b/migration/ram.c index d7505f5368..75de936bd2 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -1612,6 +1612,28 @@ out: return ret; } =20 +static inline void populate_range(RAMBlock *block, hwaddr offset, hwaddr s= ize) +{ + char *ptr =3D (char *) block->host; + + for (; offset < size; offset +=3D qemu_real_host_page_size) { + char tmp =3D *(ptr + offset); + + /* Don't optimize the read out */ + asm volatile("" : "+r" (tmp)); + } +} + +static inline int populate_section(MemoryRegionSection *section, void *opa= que) +{ + const hwaddr size =3D int128_get64(section->size); + hwaddr offset =3D section->offset_within_region; + RAMBlock *block =3D section->mr->ram_block; + + populate_range(block, offset, size); + return 0; +} + /* * ram_block_populate_pages: populate memory in the RAM block by reading * an integer from the beginning of each page. @@ -1621,16 +1643,31 @@ out: * * @block: RAM block to populate */ -static void ram_block_populate_pages(RAMBlock *block) +static void ram_block_populate_pages(RAMBlock *rb) { - char *ptr =3D (char *) block->host; - - for (ram_addr_t offset =3D 0; offset < block->used_length; - offset +=3D qemu_real_host_page_size) { - char tmp =3D *(ptr + offset); + /* + * Skip populating all pages that fall into a discarded range as manag= ed by + * a RamDiscardManager responsible for the mapped memory region of the + * RAMBlock. Such discarded ("logically unplugged") parts of a RAMBlock + * must not get populated automatically. We don't have to track + * modifications via userfaultfd WP reliably, because these pages will + * not be part of the migration stream either way -- see + * ramblock_dirty_bitmap_exclude_discarded_pages(). + * + * Note: The result is only stable while migration (precopy/postcopy). + */ + if (rb->mr && memory_region_has_ram_discard_manager(rb->mr)) { + RamDiscardManager *rdm =3D memory_region_get_ram_discard_manager(r= b->mr); + MemoryRegionSection section =3D { + .mr =3D rb->mr, + .offset_within_region =3D 0, + .size =3D rb->mr->size, + }; =20 - /* Don't optimize the read out */ - asm volatile("" : "+r" (tmp)); + ram_discard_manager_replay_populated(rdm, §ion, + populate_section, NULL); + } else { + populate_range(rb, 0, qemu_ram_get_used_length(rb)); } } =20 --=20 2.31.1