migration: Introduce postcopy incoming setup and cleanup functions

After moving postcopy_ram_listen_thread() to postcopy file, this patch
introduces a pair of functions, postcopy_incoming_setup() and
postcopy_incoming_cleanup(). These functions encapsulate setup and
cleanup of all incoming postcopy resources, postcopy-ram and postcopy
listen thread.

Furthermore, this patch also renames the postcopy_ram_listen_thread to
postcopy_listen_thread, as this thread handles not only postcopy-ram,
but also dirty-bitmaps and in the future it could handle other
postcopiable devices.

Signed-off-by: Juraj Marcin <jmarcin@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Link: https://lore.kernel.org/r/20251103183301.3840862-5-jmarcin@redhat.com
Signed-off-by: Peter Xu <peterx@redhat.com>
This commit is contained in:
Juraj Marcin 2025-11-03 19:32:53 +01:00 committed by Peter Xu
parent c9aac1ae10
commit 67474ebacc
4 changed files with 47 additions and 27 deletions

View file

@ -892,7 +892,7 @@ process_incoming_migration_co(void *opaque)
* but managed to complete within the precopy period, we can use
* the normal exit.
*/
postcopy_ram_incoming_cleanup(mis);
postcopy_incoming_cleanup(mis);
} else if (ret >= 0) {
/*
* Postcopy was started, cleanup should happen at the end of the

View file

@ -2083,7 +2083,7 @@ bool postcopy_is_paused(MigrationStatus status)
* the input stream, leaving the main thread free to carry on loading the rest
* of the device state (from RAM).
*/
void *postcopy_ram_listen_thread(void *opaque)
static void *postcopy_listen_thread(void *opaque)
{
MigrationIncomingState *mis = migration_incoming_get_current();
QEMUFile *f = mis->from_src_file;
@ -2149,7 +2149,7 @@ void *postcopy_ram_listen_thread(void *opaque)
*/
qemu_event_wait(&mis->main_thread_load_event);
}
postcopy_ram_incoming_cleanup(mis);
postcopy_incoming_cleanup(mis);
if (load_res < 0) {
/*
@ -2182,3 +2182,43 @@ void *postcopy_ram_listen_thread(void *opaque)
return NULL;
}
int postcopy_incoming_setup(MigrationIncomingState *mis, Error **errp)
{
/*
* Sensitise RAM - can now generate requests for blocks that don't exist
* However, at this point the CPU shouldn't be running, and the IO
* shouldn't be doing anything yet so don't actually expect requests
*/
if (migrate_postcopy_ram()) {
if (postcopy_ram_incoming_setup(mis)) {
postcopy_ram_incoming_cleanup(mis);
error_setg(errp, "Failed to setup incoming postcopy RAM blocks");
return -1;
}
}
trace_loadvm_postcopy_handle_listen("after uffd");
if (postcopy_notify(POSTCOPY_NOTIFY_INBOUND_LISTEN, errp)) {
return -1;
}
mis->have_listen_thread = true;
postcopy_thread_create(mis, &mis->listen_thread,
MIGRATION_THREAD_DST_LISTEN,
postcopy_listen_thread, QEMU_THREAD_DETACHED);
return 0;
}
int postcopy_incoming_cleanup(MigrationIncomingState *mis)
{
int rc = 0;
if (migrate_postcopy_ram()) {
rc = postcopy_ram_incoming_cleanup(mis);
}
return rc;
}

View file

@ -199,6 +199,7 @@ bool postcopy_is_paused(MigrationStatus status);
void mark_postcopy_blocktime_begin(uintptr_t addr, uint32_t ptid,
RAMBlock *rb);
void *postcopy_ram_listen_thread(void *opaque);
int postcopy_incoming_setup(MigrationIncomingState *mis, Error **errp);
int postcopy_incoming_cleanup(MigrationIncomingState *mis);
#endif

View file

@ -2113,32 +2113,11 @@ static int loadvm_postcopy_handle_listen(MigrationIncomingState *mis,
trace_loadvm_postcopy_handle_listen("after discard");
/*
* Sensitise RAM - can now generate requests for blocks that don't exist
* However, at this point the CPU shouldn't be running, and the IO
* shouldn't be doing anything yet so don't actually expect requests
*/
if (migrate_postcopy_ram()) {
if (postcopy_ram_incoming_setup(mis)) {
postcopy_ram_incoming_cleanup(mis);
error_setg(errp, "Failed to setup incoming postcopy RAM blocks");
return -1;
}
}
int rc = postcopy_incoming_setup(mis, errp);
trace_loadvm_postcopy_handle_listen("after uffd");
if (postcopy_notify(POSTCOPY_NOTIFY_INBOUND_LISTEN, errp)) {
return -1;
}
mis->have_listen_thread = true;
postcopy_thread_create(mis, &mis->listen_thread,
MIGRATION_THREAD_DST_LISTEN,
postcopy_ram_listen_thread, QEMU_THREAD_DETACHED);
trace_loadvm_postcopy_handle_listen("return");
return 0;
return rc;
}
static void loadvm_postcopy_handle_run_bh(void *opaque)