On Wed, Aug 19, 2026 at 9:13 PM Peter Xu <[email protected]> wrote:
>
> On Sun, Aug 16, 2026 at 11:16:20PM +0530, Aadeshveer Singh wrote:
> > This series implements a "fast snapshot load" mechanism to
> > significantly reduce the perceived resume time of a VM from a snapshot
> > file.
>
> This series breaks Windows builds... we'll need three fixups into three
> patches to fix it.  Attached at the end.
>
> For Aadeshveer: in the future you can check Windows build of your own
> patches locally by running this:
>
>   $ make docker-test-build@fedora-win64-cross
>
> I do hit Rust build failures nowadays with Windows, though, so you may need
> this if you have enabled rust builds instead (I also normally use J=N for
> concurrency):
>
>   $ J=8 EXTRA_CONFIGURE_OPTS=--disable-rust make 
> docker-test-build@fedora-win64-cross
>

Thanks for catching the Windows build failure and writing the fixups!
I've noted down the test command and will make sure any future work
does not break the windows build.

> For Fabiano: if you want, you can also directly pick up the relevant
> patches I queued in my -next branch, or squash the fixups attached, or pick
> your own fix. I'll leave that to you to decide.
>
>   https://gitlab.com/peterx/qemu/-/tree/next
>
> Thanks,
>
> ===8<===
>
>
>
> From 572b0f8b611e430e5ed8651d99851975878624c7 Mon Sep 17 00:00:00 2001
> From: Peter Xu <[email protected]>
> Date: Tue, 18 Aug 2026 16:38:08 -0400
> Subject: [PATCH 1/3] fixup! migration: Propagate error in postcopy setup
>  functions
>
> Signed-off-by: Peter Xu <[email protected]>
> ---
>  migration/postcopy-ram.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c
> index 81d06917fe..3c85fa1b19 100644
> --- a/migration/postcopy-ram.c
> +++ b/migration/postcopy-ram.c
> @@ -1906,7 +1906,7 @@ int postcopy_request_shared_page(struct PostCopyFD 
> *pcfd, RAMBlock *rb,
>      g_assert_not_reached();
>  }
>
> -int postcopy_ram_incoming_setup(MigrationIncomingState *mis)
> +int postcopy_ram_incoming_setup(MigrationIncomingState *mis, Error **errp)
>  {
>      g_assert_not_reached();
>  }
> --
> 2.54.0
>
>
>
>
> From 4273cc6ed223de1781513af9a62c1672c3f5591b Mon Sep 17 00:00:00 2001
> From: Peter Xu <[email protected]>
> Date: Wed, 19 Aug 2026 10:30:35 -0400
> Subject: [PATCH 2/3] fixup! migration: Extract blocktime marking helper
>
> Signed-off-by: Peter Xu <[email protected]>
> ---
>  migration/postcopy-ram.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
>
> diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c
> index 3c85fa1b19..fdc65c3545 100644
> --- a/migration/postcopy-ram.c
> +++ b/migration/postcopy-ram.c
> @@ -1934,6 +1934,14 @@ void mark_postcopy_blocktime_begin(uintptr_t addr, 
> uint32_t ptid,
>                                     RAMBlock *rb)
>  {
>  }
> +
> +bool try_mark_postcopy_blocktime_begin(MigrationIncomingState *mis,
> +                                       RAMBlock *rb, ram_addr_t start,
> +                                       uint64_t haddr, uint32_t tid)
> +{
> +    g_assert_not_reached();
> +    return false;
> +}
>  #endif
>
>  /* ------------------------------------------------------------------------- 
> */
> --
> 2.54.0
>
>
>
> From d2d397de73fe39b424b2871fe4ba0df7937cc680 Mon Sep 17 00:00:00 2001
> From: Peter Xu <[email protected]>
> Date: Tue, 18 Aug 2026 16:43:29 -0400
> Subject: [PATCH 3/3] fixup! migration: add eager load thread and setup for
>  fast snapshot load
>
> Signed-off-by: Peter Xu <[email protected]>
> ---
>  migration/postcopy-ram.c | 135 ++++++++++++++++++++-------------------
>  1 file changed, 71 insertions(+), 64 deletions(-)
>
> diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c
> index fdc65c3545..885ab58fca 100644
> --- a/migration/postcopy-ram.c
> +++ b/migration/postcopy-ram.c
> @@ -39,6 +39,8 @@
>  #include "qemu/mmap-alloc.h"
>  #include "options.h"
>
> +static void postcopy_incoming_complete_bh(void *opaque);
> +
>  /* Arbitrary limit on size of each discard command,
>   * keeps them around ~200 bytes
>   */
> @@ -1872,6 +1874,70 @@ int postcopy_place_page_zero(MigrationIncomingState 
> *mis, void *host,
>      }
>  }
>
> +/*
> + * Called by postcopy_ram_eager_load_thread over all blocks to load in all 
> the
> + * pending pages of given ram block
> + */
> +static int ram_block_load_eager(RAMBlock *rb, void *opaque)
> +{
> +    MigrationIncomingState *mis = migration_incoming_get_current();
> +    MigrationState *s = migrate_get_current();
> +    Error *errp = NULL;
> +    void *host = qemu_ram_get_host_addr(rb);
> +    void *target;
> +
> +    for (ram_addr_t page_loc = 0; page_loc < rb->used_length;
> +         page_loc += qemu_ram_pagesize(rb)) {
> +        target = (uint8_t *)host + page_loc;
> +        if (!postcopy_mapped_ram_load_page(mis, rb, page_loc, 
> (uint64_t)target,
> +                                           RAM_CHANNEL_PRECOPY, &errp)) {
> +            migrate_error_propagate(s, errp);
> +            return -1;
> +        }
> +    }
> +    return 0;
> +}
> +
> +/*
> + * Used by fast snapshot load to eagerly load in all pages of RAM and 
> schedule
> + * cleanup after entire RAM is loaded
> + */
> +static void *postcopy_ram_eager_load_thread(void *opaque)
> +{
> +    MigrationIncomingState *mis = opaque;
> +    MigrationStatus next_state;
> +
> +    trace_postcopy_ram_eager_load_thread_entry();
> +    rcu_register_thread();
> +    qemu_event_set(&mis->thread_sync_event);
> +
> +    if (foreach_not_ignored_block(ram_block_load_eager, NULL)) {
> +        next_state = MIGRATION_STATUS_FAILED;
> +    } else {
> +        next_state = MIGRATION_STATUS_COMPLETED;
> +    }
> +    migrate_set_state(&mis->state, MIGRATION_STATUS_POSTCOPY_ACTIVE,
> +                      next_state);
> +
> +    postcopy_state_set(POSTCOPY_INCOMING_END);
> +    migration_bh_schedule(postcopy_incoming_complete_bh, mis);
> +
> +    rcu_unregister_thread();
> +    trace_postcopy_ram_eager_load_thread_exit();
> +    return NULL;
> +}
> +
> +/*
> + * Create thread for eager loading in fast snapshot load case
> + */
> +void postcopy_ram_eager_load_setup(MigrationIncomingState *mis)
> +{
> +    postcopy_thread_create(
> +        mis, &mis->eager_load_thread, MIGRATION_THREAD_DST_SNAPSHOT_LOAD,
> +        postcopy_ram_eager_load_thread, QEMU_THREAD_JOINABLE);
> +    mis->have_eager_load_thread = true;
> +}
> +
>  #else
>  /* No target OS support, stubs just fail */
>  void fill_destination_postcopy_migration_info(MigrationInfo *info)
> @@ -1942,6 +2008,11 @@ bool 
> try_mark_postcopy_blocktime_begin(MigrationIncomingState *mis,
>      g_assert_not_reached();
>      return false;
>  }
> +
> +void postcopy_ram_eager_load_setup(MigrationIncomingState *mis)
> +{
> +    g_assert_not_reached();
> +}
>  #endif
>
>  /* ------------------------------------------------------------------------- 
> */
> @@ -2426,67 +2497,3 @@ int postcopy_incoming_cleanup(MigrationIncomingState 
> *mis)
>
>      return rc;
>  }
> -
> -/*
> - * Called by postcopy_ram_eager_load_thread over all blocks to load in all 
> the
> - * pending pages of given ram block
> - */
> -static int ram_block_load_eager(RAMBlock *rb, void *opaque)
> -{
> -    MigrationIncomingState *mis = migration_incoming_get_current();
> -    MigrationState *s = migrate_get_current();
> -    Error *errp = NULL;
> -    void *host = qemu_ram_get_host_addr(rb);
> -    void *target;
> -
> -    for (ram_addr_t page_loc = 0; page_loc < rb->used_length;
> -         page_loc += qemu_ram_pagesize(rb)) {
> -        target = (uint8_t *)host + page_loc;
> -        if (!postcopy_mapped_ram_load_page(mis, rb, page_loc, 
> (uint64_t)target,
> -                                           RAM_CHANNEL_PRECOPY, &errp)) {
> -            migrate_error_propagate(s, errp);
> -            return -1;
> -        }
> -    }
> -    return 0;
> -}
> -
> -/*
> - * Used by fast snapshot load to eagerly load in all pages of RAM and 
> schedule
> - * cleanup after entire RAM is loaded
> - */
> -static void *postcopy_ram_eager_load_thread(void *opaque)
> -{
> -    MigrationIncomingState *mis = opaque;
> -    MigrationStatus next_state;
> -
> -    trace_postcopy_ram_eager_load_thread_entry();
> -    rcu_register_thread();
> -    qemu_event_set(&mis->thread_sync_event);
> -
> -    if (foreach_not_ignored_block(ram_block_load_eager, NULL)) {
> -        next_state = MIGRATION_STATUS_FAILED;
> -    } else {
> -        next_state = MIGRATION_STATUS_COMPLETED;
> -    }
> -    migrate_set_state(&mis->state, MIGRATION_STATUS_POSTCOPY_ACTIVE,
> -                      next_state);
> -
> -    postcopy_state_set(POSTCOPY_INCOMING_END);
> -    migration_bh_schedule(postcopy_incoming_complete_bh, mis);
> -
> -    rcu_unregister_thread();
> -    trace_postcopy_ram_eager_load_thread_exit();
> -    return NULL;
> -}
> -
> -/*
> - * Create thread for eager loading in fast snapshot load case
> - */
> -void postcopy_ram_eager_load_setup(MigrationIncomingState *mis)
> -{
> -    postcopy_thread_create(
> -        mis, &mis->eager_load_thread, MIGRATION_THREAD_DST_SNAPSHOT_LOAD,
> -        postcopy_ram_eager_load_thread, QEMU_THREAD_JOINABLE);
> -    mis->have_eager_load_thread = true;
> -}
> --
> 2.54.0
>
>
> --
> Peter Xu
>

Reply via email to