During post-copy migration (once it actually switches to post-copy mode)
dirty memory pages are continued to be migrated iteratively, while the
destination can explicitly request a specific page to be migrated before
the iterative process gets to it (which happens when a guest wants to
read a page that was not migrated yet). Without the postcopy-preempt
capability enabled such pages need to wait until all other pages already
queued are transferred. Enabling this capability will instruct the
hypervisor to create a separate migration channel for explicitly
requested pages so that they can preempt the queue.
This is enabled for all post-copy migration as long as the capability is
supported on both sides of migration.
Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
src/qemu/qemu_migration.c | 11 +++++++----
src/qemu/qemu_migration_params.c | 2 ++
src/qemu/qemu_migration_params.h | 1 +
3 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 5504119079..25dc16a9e9 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -5203,17 +5203,20 @@ qemuMigrationSrcPerformNative(virQEMUDriver *driver,
return -1;
}
- if (flags & VIR_MIGRATE_PARALLEL)
+ /* multi-fd and postcopy-preempt require QEMU to connect to the
+ * destination itself */
+ if (flags & (VIR_MIGRATE_PARALLEL | VIR_MIGRATE_POSTCOPY))
spec.destType = MIGRATION_DEST_SOCKET;
else
spec.destType = MIGRATION_DEST_CONNECT_SOCKET;
spec.dest.socket.path = uribits->path;
} else {
- /* RDMA and multi-fd migration requires QEMU to connect to the destination
- * itself.
+ /* RDMA, multi-fd, and postcopy-preempt migration require QEMU to
+ * connect to the destination itself.
*/
- if (STREQ(uribits->scheme, "rdma") || (flags &
VIR_MIGRATE_PARALLEL))
+ if (STREQ(uribits->scheme, "rdma") ||
+ flags & (VIR_MIGRATE_PARALLEL | VIR_MIGRATE_POSTCOPY))
spec.destType = MIGRATION_DEST_HOST;
else
spec.destType = MIGRATION_DEST_CONNECT_HOST;
diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c
index 133f1f762d..9a399c7162 100644
--- a/src/qemu/qemu_migration_params.c
+++ b/src/qemu/qemu_migration_params.c
@@ -104,6 +104,7 @@ VIR_ENUM_IMPL(qemuMigrationCapability,
"dirty-bitmaps",
"return-path",
"zero-copy-send",
+ "postcopy-preempt",
);
@@ -197,6 +198,7 @@ static const qemuMigrationParamsFlagMapItem
qemuMigrationParamsFlagMap[] = {
{.match = QEMU_MIGRATION_FLAG_REQUIRED,
.flag = VIR_MIGRATE_POSTCOPY,
.cap = QEMU_MIGRATION_CAP_POSTCOPY,
+ .optional = QEMU_MIGRATION_CAP_POSTCOPY_PREEMPT,
.party = QEMU_MIGRATION_SOURCE | QEMU_MIGRATION_DESTINATION},
{.match = QEMU_MIGRATION_FLAG_REQUIRED,
diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h
index 115d7bc597..91bc6792cd 100644
--- a/src/qemu/qemu_migration_params.h
+++ b/src/qemu/qemu_migration_params.h
@@ -40,6 +40,7 @@ typedef enum {
QEMU_MIGRATION_CAP_BLOCK_DIRTY_BITMAPS,
QEMU_MIGRATION_CAP_RETURN_PATH,
QEMU_MIGRATION_CAP_ZERO_COPY_SEND,
+ QEMU_MIGRATION_CAP_POSTCOPY_PREEMPT,
QEMU_MIGRATION_CAP_LAST
} qemuMigrationCapability;
--
2.43.0