From nobody Sat Sep 26 20:51:00 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=quarantine dis=none) header.from=openvz.org ARC-Seal: i=1; a=rsa-sha256; t=1789136686; cv=none; d=zohomail.com; s=zohoarc; b=NLqkrRcbCSku9LgeEzZmqVXyW4fmzS9v7pHdIrQz+/nIvqm9BG6brGPGZXk2yQuOpolHFEvf1/4adM01WyFbyZW4OwY08hWi/xuq9LHusLPUf/M2e4STkURoYAixiz8c+XtV68KHDr/VYkMfRXnaXHLV633oiDxjHX5+bPRRq0E= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1789136686; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=VE+MVcm8/cLaSkZ698BO2DSG7Db82s9o5WJWIxU2Vx0=; b=BJZHyPTtskyjLnnU/4el8SqTaoilqjbQ3Cf1l3bbM/uYAz/ROGDgWbRRDewNWsQ1gMH+8cD/wkuLXVCMiPUqWvo9z1a3WeCzybDdRrKmdSqRrFALwoU+Tj2FnTMQXZu5vXoM0UQA8nrkSckThHmoRdVb7CSEWqXohV+3I+14XFk= 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=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1789136686416896.4032347320614; Fri, 11 Sep 2026 07:24:46 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x52Az-0003h3-8P; Fri, 11 Sep 2026 10:24:25 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x52AX-0003UN-5o for qemu-devel@nongnu.org; Fri, 11 Sep 2026 10:23:58 -0400 Received: from mail-wr1-x42c.google.com ([2a00:1450:4864:20::42c]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1x52AT-000567-3I for qemu-devel@nongnu.org; Fri, 11 Sep 2026 10:23:55 -0400 Received: by mail-wr1-x42c.google.com with SMTP id ffacd0b85a97d-482ea739de2so649919f8f.0 for ; Fri, 11 Sep 2026 07:23:52 -0700 (PDT) Received: from athena.sw.ru ([2a06:5b06:b600:300:a007:bd26:918e:c58]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-486eb33ee5csm6398448f8f.20.2026.09.11.07.23.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Sep 2026 07:23:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=openvz.org; s=google; t=1789136631; x=1789741431; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=VE+MVcm8/cLaSkZ698BO2DSG7Db82s9o5WJWIxU2Vx0=; b=XR+qVjX4kTnc+O5yOpOiy4iB91zH0D35sDgXsRJ7CriGYx5lxrNCvDOQxBTfLYMUFi hT4mpbIPRUiQx4XT7OOZQ23WeSwLLP/TzleIvtMShwKgs20dTQ8p5dmJxTZe8Cr+oqr3 NO6lujvBeQ4NL2EReJYyU1AecoXX+qkDFpUezU4z3kKpUrwjIGx3R8ze0D+lx5NIw7FK 9If6qLqFrnjK4C1EwemKg0Z/Jb1zlXpRV6gnN5saMdLDv4+zUxB2plyxg9kyCqaA1njx k9+Sina4WUZdTDe2vETHGJA4uBHKUIQ76TZ3MbQ6OXV/qguMjn1YfDpk346w2mefeJ4z F1wA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789136631; x=1789741431; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=VE+MVcm8/cLaSkZ698BO2DSG7Db82s9o5WJWIxU2Vx0=; b=l3sklTukHug7tDK5rky/Rwfd6S3zXDlghocg7MwUe/9LVuWZvXhqrMAL4fnhxiw9+B Y5BVJOtTPHIpPRrFf9B1KLGl1BTeY9uam7isuWQhKwHbCGm4jYMPadLWN3D42LY+dMvy 1l1g6vs65UaxIZp8kfzFPdbG9TF6r8d6/oES5300tdy8DAEtkFwy7CRT2k6xBdI+XiCT B2N1awY565mR13rd2B8nuZF3WbeQ+MyodeNE8cuSknYOOR+KViDPqawjQETWp/V4yrAC cK4395ihGAy+7PDNvJ4AdEKSsfXshSFRgC5J/3a6n4tLS4UR56Ogi/NhfA3THNfFQwIo ak6w== X-Gm-Message-State: AFuF++lIZaMbZTS0hamMzprzyT2+rkEDiSOgeTxzsa0YN61RyO/llsOn OIOdwBix5Q7UmROQ6U9WpAZxeBXDRMm3x7216bbTOOrBpndT8v4XoYocr92ynvbO3iQtK9Iz/Xh Dl/+C X-Gm-Gg: AYBFou33L9L/wAQ/ggbMjrz0nCzA7wP6JtL4cUSRlzmiumsYgjaerRWJfUxlcbEZSfD EdF2qyJGfyzGRqQ6QGQAgRZhUp0jeidL3E0zvN8HuZBnoVlbvA01nVEVVIVgtsONlrkJadeokl+ B5ORtUD0eziIo6c9esEqdK/eXDTiboxh6Tqer1ZNOcXTSv+itVM2p0mRiQ6Do+v7dP6PKPMbXMb Y5FX6dgLtlFoRyPxpmyxtJZm5pvygi5yMNt7e0eJJbz4gZxlYSJ1nHhtg7MEUct8L0qukrLg/Pz 8lZbRsCyPZcA/5yulidV/MfAd/aipRS9R1aUGd8OTH00ake1ZSapoV+ONbppwZMwwhxit6flCgN l7rA/ksJV9s48yktDlZaJcWuzLBUuLz1ayZHiamwEA86Yo9e0tMH9maShmv58rV4aiDnPQilvo3 57xFyLv6/VuQkWwNgcordbLF9nqNJGyBF3qU6VXfhecChYnlBOmV7XKkKAmaZ+EtObAd8= X-Received: by 2002:a05:6000:c84:b0:482:e10e:58df with SMTP id ffacd0b85a97d-486eb303607mr4100158f8f.21.1789136631120; Fri, 11 Sep 2026 07:23:51 -0700 (PDT) From: "Denis V. Lunev" To: qemu-devel@nongnu.org Cc: den@openvz.org, Peter Xu , Fabiano Rosas , Paolo Bonzini , Zhao Liu , "Denis V. Lunev" Subject: [PATCH 1/2] migration: let a vmstate defer its post_load to end of stream Date: Fri, 11 Sep 2026 16:23:44 +0200 Message-ID: <20260911142345.3999518-2-den@openvz.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260911142345.3999518-1-den@openvz.org> References: <20260911142345.3999518-1-den@openvz.org> MIME-Version: 1.0 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=lists1p.gnu.org; Received-SPF: pass client-ip=2a00:1450:4864:20::42c; envelope-from=den@openvz.org; helo=mail-wr1-x42c.google.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, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, 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: qemu development 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 @openvz.org) X-ZM-MESSAGEID: 1789136688217158500 Content-Type: text/plain; charset="utf-8" From: Denis V. Lunev A post_load hook which only rearranges the memory topology forces a flatview rebuild as its section is read, and the cost of a rebuild grows with the number of regions in the machine. A device which does this once per vCPU therefore scales badly on the destination. Add post_load_deferrable. A vmsd which sets it has its hook queued during the load and run once the stream has been consumed, in the order the hooks would have fired, with the whole drain sharing one memory transaction. Opt-in, because deferral is not free in general. A hook which can fail must not be deferred: failing after the stream is consumed means the source has already been told the migration succeeded, and may release a guest the destination never started. A hook which reads guest memory must not be deferred either, since the drain runs with the topology in flux. Postcopy is excluded because its listen thread walks the same stream concurrently. CC: Peter Xu CC: Fabiano Rosas CC: Paolo Bonzini CC: Zhao Liu Signed-off-by: Denis V. Lunev --- include/migration/vmstate.h | 40 +++++++++++++ migration/savevm.c | 23 ++++++++ migration/vmstate.c | 67 +++++++++++++++++++++- tests/unit/test-vmstate.c | 111 ++++++++++++++++++++++++++++++++++++ 4 files changed, 239 insertions(+), 2 deletions(-) diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h index e72c3fae9a..16045319d5 100644 --- a/include/migration/vmstate.h +++ b/include/migration/vmstate.h @@ -303,6 +303,29 @@ struct VMStateDescription { bool (*pre_load_errp)(void *opaque, Error **errp); int (*post_load)(void *opaque, int version_id); bool (*post_load_errp)(void *opaque, int version_id, Error **errp); + + /* + * Run .post_load() once the whole stream has been loaded rather than + * as this section is read, so that it sees a machine whose devices + * have all been restored, and so that several of them can share the + * work they would each repeat. + * + * Three things must hold of a hook before it may be deferred. + * + * It must not fail. By the time the queue is drained the stream has + * been consumed, so a source may already have been told the migration + * succeeded and may have released the guest; there is nothing left to + * report a failure to. A hook which fails here is a bug in its vmsd + * and is fatal. + * + * Nothing else in the load may depend on what it does. The hooks run + * after every section has been read, so anything a later section needs + * to observe must not be produced here. + * + * It must not read guest memory or resolve an address space, because + * the drain runs as one batch with the memory topology in flux. + */ + bool post_load_deferrable; int (*pre_save)(void *opaque); bool (*pre_save_errp)(void *opaque, Error **errp); =20 @@ -1299,6 +1322,23 @@ bool vmstate_save_vmsd(QEMUFile *f, const VMStateDes= cription *vmsd, =20 bool vmstate_section_needed(const VMStateDescription *vmsd, void *opaque); =20 +/** + * vmstate_post_load_defer_begin: Queue deferrable post_load hooks + * + * Between this and vmstate_post_load_defer_finish(), a post_load hook who= se + * vmsd sets post_load_deferrable is recorded rather than called. Hooks are + * queued in the order they would have run. + */ +void vmstate_post_load_defer_begin(void); + +/** + * vmstate_post_load_defer_finish: Stop deferring and drain the queue + * @run: run the queued hooks, in order; when false, discard them + * + * Returns false if a hook failed, in which case the rest are discarded. + */ +bool vmstate_post_load_defer_finish(bool run, Error **errp); + #define VMSTATE_INSTANCE_ID_ANY -1 =20 /* Returns: 0 on success, -1 on failure */ diff --git a/migration/savevm.c b/migration/savevm.c index 4b590ea672..2352dcf684 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -3128,6 +3128,7 @@ int qemu_loadvm_state(QEMUFile *f, Error **errp) { MigrationState *s =3D migrate_get_current(); MigrationIncomingState *mis =3D migration_incoming_get_current(); + bool defer_post_load; int ret; =20 if (qemu_savevm_state_blocked(errp)) { @@ -3147,7 +3148,29 @@ int qemu_loadvm_state(QEMUFile *f, Error **errp) =20 cpu_synchronize_all_pre_loadvm(); =20 + /* + * The postcopy listen thread walks the same stream concurrently, so t= he + * queue would need locking and a defined owner for the drain. + */ + defer_post_load =3D !migrate_postcopy_ram(); + if (defer_post_load) { + vmstate_post_load_defer_begin(); + } + ret =3D qemu_loadvm_state_main(f, mis, errp); + + if (defer_post_load) { + /* + * A deferrable hook only rearranges the memory topology, so the + * whole drain can share one flatview rebuild. + */ + memory_region_transaction_begin(); + if (!vmstate_post_load_defer_finish(ret =3D=3D 0, errp)) { + ret =3D -EINVAL; + } + memory_region_transaction_commit(); + } + qemu_event_set(&mis->main_thread_load_event); =20 trace_qemu_loadvm_state_post_main(ret); diff --git a/migration/vmstate.c b/migration/vmstate.c index 24004565bf..3745f80dc8 100644 --- a/migration/vmstate.c +++ b/migration/vmstate.c @@ -250,8 +250,19 @@ static bool vmstate_load_field(QEMUFile *f, void *pv, = size_t size, return true; } =20 -static bool vmstate_post_load(const VMStateDescription *vmsd, - void *opaque, int version_id, Error **errp) +typedef struct VMStateDeferredPostLoad { + const VMStateDescription *vmsd; + void *opaque; + int version_id; + QSIMPLEQ_ENTRY(VMStateDeferredPostLoad) entry; +} VMStateDeferredPostLoad; + +static QSIMPLEQ_HEAD(, VMStateDeferredPostLoad) vmstate_deferred_post_load= s =3D + QSIMPLEQ_HEAD_INITIALIZER(vmstate_deferred_post_loads); +static bool vmstate_defer_post_load; + +static bool vmstate_do_post_load(const VMStateDescription *vmsd, + void *opaque, int version_id, Error **err= p) { ERRP_GUARD(); =20 @@ -277,6 +288,58 @@ static bool vmstate_post_load(const VMStateDescription= *vmsd, return true; } =20 +static bool vmstate_post_load(const VMStateDescription *vmsd, + void *opaque, int version_id, Error **errp) +{ + VMStateDeferredPostLoad *d; + + if (!vmstate_defer_post_load || !vmsd->post_load_deferrable) { + return vmstate_do_post_load(vmsd, opaque, version_id, errp); + } + + d =3D g_new(VMStateDeferredPostLoad, 1); + d->vmsd =3D vmsd; + d->opaque =3D opaque; + d->version_id =3D version_id; + QSIMPLEQ_INSERT_TAIL(&vmstate_deferred_post_loads, d, entry); + + return true; +} + +void vmstate_post_load_defer_begin(void) +{ + assert(!vmstate_defer_post_load); + assert(QSIMPLEQ_EMPTY(&vmstate_deferred_post_loads)); + vmstate_defer_post_load =3D true; +} + +bool vmstate_post_load_defer_finish(bool run, Error **errp) +{ + VMStateDeferredPostLoad *d; + bool ok =3D true; + + vmstate_defer_post_load =3D false; + + while ((d =3D QSIMPLEQ_FIRST(&vmstate_deferred_post_loads))) { + QSIMPLEQ_REMOVE_HEAD(&vmstate_deferred_post_loads, entry); + if (run) { + ERRP_GUARD(); + + if (!vmstate_do_post_load(d->vmsd, d->opaque, d->version_id, + errp)) { + error_prepend(errp, "deferrable post load hook failed, whi= ch " + "its vmsd promised could not happen: "); + error_report_err(*errp); + *errp =3D NULL; + abort(); + } + } + g_free(d); + } + + return ok; +} + /* * Try to prepare loading the next element, the object pointer to be put * into @next_elem. When @next_elem is NULL, it means we should skip diff --git a/tests/unit/test-vmstate.c b/tests/unit/test-vmstate.c index df1fb4c778..e1e64b23c2 100644 --- a/tests/unit/test-vmstate.c +++ b/tests/unit/test-vmstate.c @@ -1619,6 +1619,116 @@ static void test_tmp_struct(void) g_assert_cmpint(obj.f, =3D=3D, 8); /* From the child->parent */ } =20 +/* Deferred post_load */ + +static int defer_order; +static int defer_a_ran; +static int defer_b_ran; +static int defer_inline_ran; + +static int defer_a_post_load(void *opaque, int version_id) +{ + defer_a_ran =3D ++defer_order; + return 0; +} + +static int defer_b_post_load(void *opaque, int version_id) +{ + defer_b_ran =3D ++defer_order; + return 0; +} + +static int defer_inline_post_load(void *opaque, int version_id) +{ + defer_inline_ran =3D ++defer_order; + return 0; +} + +static const VMStateDescription vmstate_defer_a =3D { + .name =3D "test/defer_a", + .version_id =3D 1, + .post_load =3D defer_a_post_load, + .post_load_deferrable =3D true, + .fields =3D (const VMStateField[]) { + VMSTATE_UINT32(a, TestStruct), + VMSTATE_END_OF_LIST() + } +}; + +static const VMStateDescription vmstate_defer_b =3D { + .name =3D "test/defer_b", + .version_id =3D 1, + .post_load =3D defer_b_post_load, + .post_load_deferrable =3D true, + .fields =3D (const VMStateField[]) { + VMSTATE_UINT32(a, TestStruct), + VMSTATE_END_OF_LIST() + } +}; + +static const VMStateDescription vmstate_defer_inline =3D { + .name =3D "test/defer_inline", + .version_id =3D 1, + .post_load =3D defer_inline_post_load, + .fields =3D (const VMStateField[]) { + VMSTATE_UINT32(a, TestStruct), + VMSTATE_END_OF_LIST() + } +}; + +static void defer_reset(void) +{ + defer_order =3D 0; + defer_a_ran =3D 0; + defer_b_ran =3D 0; + defer_inline_ran =3D 0; +} + +static void test_post_load_defer(void) +{ + uint8_t const wire[] =3D { + /* uint32 a */ 0x00, 0x00, 0x00, 0x01, + QEMU_VM_EOF, + }; + TestStruct obj; + Error *err =3D NULL; + + /* Not deferring: a deferrable hook still runs as the section is read = */ + defer_reset(); + memset(&obj, 0, sizeof(obj)); + SUCCESS(load_vmstate_one(&vmstate_defer_a, &obj, 1, wire, sizeof(wire)= )); + g_assert_cmpint(defer_a_ran, =3D=3D, 1); + + /* + * Deferring holds back the hooks which opted in and replays them in t= he + * order they would have run. A hook which did not opt in is unaffecte= d. + */ + defer_reset(); + memset(&obj, 0, sizeof(obj)); + vmstate_post_load_defer_begin(); + SUCCESS(load_vmstate_one(&vmstate_defer_a, &obj, 1, wire, sizeof(wire)= )); + SUCCESS(load_vmstate_one(&vmstate_defer_inline, &obj, 1, wire, + sizeof(wire))); + SUCCESS(load_vmstate_one(&vmstate_defer_b, &obj, 1, wire, sizeof(wire)= )); + g_assert_cmpint(defer_a_ran, =3D=3D, 0); + g_assert_cmpint(defer_b_ran, =3D=3D, 0); + g_assert_cmpint(defer_inline_ran, =3D=3D, 1); + + g_assert(vmstate_post_load_defer_finish(true, &err)); + g_assert(!err); + g_assert_cmpint(defer_a_ran, =3D=3D, 2); + g_assert_cmpint(defer_b_ran, =3D=3D, 3); + + /* A discarded queue runs nothing */ + defer_reset(); + memset(&obj, 0, sizeof(obj)); + vmstate_post_load_defer_begin(); + SUCCESS(load_vmstate_one(&vmstate_defer_a, &obj, 1, wire, sizeof(wire)= )); + g_assert(vmstate_post_load_defer_finish(false, &err)); + g_assert(!err); + g_assert_cmpint(defer_a_ran, =3D=3D, 0); +} + int main(int argc, char **argv) { g_autofree char *temp_file =3D g_strdup_printf("%s/vmst.test.XXXXXX", @@ -1663,6 +1773,7 @@ int main(int argc, char **argv) g_test_add_func("/vmstate/qlist/save/saveqlist", test_save_qlist); g_test_add_func("/vmstate/qlist/load/loadqlist", test_load_qlist); g_test_add_func("/vmstate/tmp_struct", test_tmp_struct); + g_test_add_func("/vmstate/post_load/defer", test_post_load_defer); g_test_run(); =20 close(temp_fd); --=20 2.53.0 From nobody Sat Sep 26 20:51:00 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=quarantine dis=none) header.from=openvz.org ARC-Seal: i=1; a=rsa-sha256; t=1789136686; cv=none; d=zohomail.com; s=zohoarc; b=C1MYiRxDAulzDE359hn7GHDDGrQ8ClX2lttIcjk1CE3JbEwqFbLSFDxjGsah/O8Ev8Jo3UquNGe5IZdclhcEXefrBmy9mX3SVFWy6nKQ6ruoZYkgEFfKf25pUplk/SaK6Gjsgz+KFvUYNytBWeCEdw7fk8GJabZpu32hxa8Kuw0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1789136686; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=U1mIQLiwrkCzh5A8cu6QdkDKni7h+rt/7QFQQbiOtwE=; b=FRWioZ64/Vf+GY9rZdWl2reCKQDmtPVp08mPB3e9KfX8jgjjDfIDkO2HMnoi+F5dAvBQx5pYxT0zTdF0JhSmW7wmFOtcOK8UofV1yP8g86OYj6v0Qm2ZPF4WI5k9qFp4jmmb+AxvaTfIWzC8+LaSQf0Q9Jfq6kvWNCrD1L1LRZo= 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=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1789136686415933.7623441905664; Fri, 11 Sep 2026 07:24:46 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x52Ay-0003gb-QM; Fri, 11 Sep 2026 10:24:24 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x52AX-0003UM-5m for qemu-devel@nongnu.org; Fri, 11 Sep 2026 10:23:58 -0400 Received: from mail-wm1-x331.google.com ([2a00:1450:4864:20::331]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1x52AT-00056F-SX for qemu-devel@nongnu.org; Fri, 11 Sep 2026 10:23:55 -0400 Received: by mail-wm1-x331.google.com with SMTP id 5b1f17b1804b1-49b96837ca3so8302675e9.3 for ; Fri, 11 Sep 2026 07:23:53 -0700 (PDT) Received: from athena.sw.ru ([2a06:5b06:b600:300:a007:bd26:918e:c58]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-486eb33ee5csm6398448f8f.20.2026.09.11.07.23.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Sep 2026 07:23:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=openvz.org; s=google; t=1789136632; x=1789741432; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=U1mIQLiwrkCzh5A8cu6QdkDKni7h+rt/7QFQQbiOtwE=; b=IkKHhXZCdb7IfxrbGls/5GbeYd+zlpvKF+hqTRsHhNvc2gOGqDgLeUiyc4j4cQYDGm htMD9aSOKzm0csdZpF98bktHDkw9c5z0s9JUDfh7cQxtlZNLJYZYxB22CjahoXDQpYKl 2QqvQsOD9M5OoN2934fl3KEvKJzTxGrl3W77mbc6jIFWhFO1/9Jik3XppSvveQea6MM4 yyhXcfOpS41JtY3CiOXMr/rzPLecsg8x1ZPqJW+sb7YsA6Ph6oBPjqHOnLRVfMMBhP4Q kOM88ZicKhcs7L9z6UapBMUD5Rr9fj79MePLmfy882BEii5eyvXaFvDrYlseotX03WUn nRNg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789136632; x=1789741432; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=U1mIQLiwrkCzh5A8cu6QdkDKni7h+rt/7QFQQbiOtwE=; b=HvVXg66Haiv1Sj9E37HICNr9P4sbLSPex9nGoOZG3eN9nILZKRlD07c8ROr0EpslVM WvBMkr1EFzV+K5epUa/V8BOZ7f0joMFlhx98W+YAhKi0o+zgb/L7l+H/F9fVBkjUfPaY Ytx73ngoimqIo6PQx238jb1dHg9dlTvnFzK9LkdrKoNbVsFCvSbyUp/FrrECmRHUrkxe cs0omIbY5RM6r05KT0EFZAYqwTIcxpfZi3LuUf+vwEO/fahePAkfmxkH1qZN+9xhrMTR ViTrQBCdj4szl91MVOJ1EczTMc5DgSAqi310ALw0km+ip67PJfTmEzjfFpBmA3nJjhfv EjBg== X-Gm-Message-State: AFuF++kVP/6tMTOhyLBkP6Q/4j1GzqUR79VyvfvmE2qPqHGSW9kYowF2 eCq9ABnk2M+i3Ug2xwp/ru91vLyamprOADw7wF4Sov88dougJxz60ANZtRcdarie7iHH9dLSahZ 348+z X-Gm-Gg: AYBFou0TQNOol1kpq08kUPkBQpw1nMY7lMtyw46IZ3W4vSoZmrI+eV5UQuYmgXPxpVK lrZ4RLUbZvTP2VNKyt4+8tIaA+xtQ0y9OwSXoyBYUfQQ5BjknE9B/saAYMwxZ53W3S65bm6tOnJ a314zROT8/XcVKZM9w8jX7j5c+uz7dsYICVxtgT8u5ygBI4UzmxcVWJBNhHQTX0RBxuzN54TOUf EOcPsq7avcDBgraNCF+RkpkrRjjLchOmQEbT1dmQHHJuNYznUNjVVE4gAFNx7NSdJ0u6bHMMlOl D2ae7cLAgS7/OOGnWDrpb0fNg1QYo0xfNbTJSWXP+lUYSQCMql7NVqVk2eKSZGeOCVVG5eHhx85 S7eBwYVmFDVe6KUy9YLW2Adm+0M04LEhKi+FYlAMcpz+qrdK0jp8UWbjOiXyBT+hQN/CD8gBb61 PyubZNw0Pywaj1uydjZXVnW1H005NHpZUEvQTLd8Mkqr3g/8Qybly/mebH0H+CfsX6AEc= X-Received: by 2002:a05:600c:a016:b0:49c:ffe3:2b3f with SMTP id 5b1f17b1804b1-49e619a0458mr53983135e9.3.1789136632358; Fri, 11 Sep 2026 07:23:52 -0700 (PDT) From: "Denis V. Lunev" To: qemu-devel@nongnu.org Cc: den@openvz.org, Peter Xu , Fabiano Rosas , Paolo Bonzini , Zhao Liu , "Denis V. Lunev" Subject: [PATCH 2/2] target/i386: defer the Hyper-V SynIC post_load Date: Fri, 11 Sep 2026 16:23:45 +0200 Message-ID: <20260911142345.3999518-3-den@openvz.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260911142345.3999518-1-den@openvz.org> References: <20260911142345.3999518-1-den@openvz.org> MIME-Version: 1.0 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=lists1p.gnu.org; Received-SPF: pass client-ip=2a00:1450:4864:20::331; envelope-from=den@openvz.org; helo=mail-wm1-x331.google.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, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, 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: qemu development 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 @openvz.org) X-ZM-MESSAGEID: 1789136688061158500 Content-Type: text/plain; charset="utf-8" From: Denis V. Lunev hyperv_synic_post_load() maps the SynIC message and event pages, and a guest which has programmed the SynIC carries the subsection on every vCPU, so restoring one rebuilds the flatview per vCPU rather than once. The hook cannot fail and does not read guest memory, so it can run with the rest of the deferred hooks once the stream has been consumed. The saving scales with vCPU count. CC: Peter Xu CC: Fabiano Rosas CC: Paolo Bonzini CC: Zhao Liu Signed-off-by: Denis V. Lunev --- target/i386/machine.c | 1 + 1 file changed, 1 insertion(+) diff --git a/target/i386/machine.c b/target/i386/machine.c index 8d69d7e25e..eae74e33de 100644 --- a/target/i386/machine.c +++ b/target/i386/machine.c @@ -873,6 +873,7 @@ static const VMStateDescription vmstate_msr_hyperv_syni= c =3D { .minimum_version_id =3D 1, .needed =3D hyperv_synic_enable_needed, .post_load =3D hyperv_synic_post_load, + .post_load_deferrable =3D true, .fields =3D (const VMStateField[]) { VMSTATE_UINT64(env.msr_hv_synic_control, X86CPU), VMSTATE_UINT64(env.msr_hv_synic_evt_page, X86CPU), --=20 2.53.0