Resolves:
https://gitlab.com/libvirt/libvirt/-/issues/306
Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
src/qemu/qemu_migration.c | 21 +++++++++++++++++++++
src/qemu/qemu_migration.h | 1 +
src/qemu/qemu_migration_params.c | 6 ++++++
src/qemu/qemu_migration_params.h | 1 +
4 files changed, 29 insertions(+)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 272f1b1b59..02a465f6cb 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2634,6 +2634,12 @@ qemuMigrationSrcBeginPhase(virQEMUDriver *driver,
}
}
+ if (flags & VIR_MIGRATE_ZEROCOPY && !(flags & VIR_MIGRATE_PARALLEL))
{
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("zero-copy is only available for parallel
migration"));
+ return NULL;
+ }
+
if (flags & (VIR_MIGRATE_NON_SHARED_DISK | VIR_MIGRATE_NON_SHARED_INC)) {
if (flags & VIR_MIGRATE_NON_SHARED_SYNCHRONOUS_WRITES &&
!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV)) {
@@ -4798,6 +4804,21 @@ qemuMigrationSrcRun(virQEMUDriver *driver,
migParams) < 0)
goto error;
+ if (flags & VIR_MIGRATE_ZEROCOPY) {
+ /* Zero-copy requires pages in transfer to be locked in host memory.
+ * Unfortunately, we have no reliable way of computing how many pages
+ * will need to be locked at the same time. Thus we set the limit to
+ * the whole guest memory and reset it back once migration is done. */
+ unsigned long long limit;
+
+ if (virMemoryLimitIsSet(vm->def->mem.hard_limit))
+ limit = vm->def->mem.hard_limit;
+ else
+ limit = virDomainDefGetMemoryTotal(vm->def);
+
+ if (qemuDomainSetMaxMemLock(vm, limit << 10,
&priv->preMigrationMemlock) < 0)
+ goto error;
+ }
if (storageMigration) {
if (mig->nbd) {
diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h
index fbc0549b34..81cc1e91c0 100644
--- a/src/qemu/qemu_migration.h
+++ b/src/qemu/qemu_migration.h
@@ -61,6 +61,7 @@
VIR_MIGRATE_PARALLEL | \
VIR_MIGRATE_NON_SHARED_SYNCHRONOUS_WRITES | \
VIR_MIGRATE_POSTCOPY_RESUME | \
+ VIR_MIGRATE_ZEROCOPY | \
0)
/* All supported migration parameters and their types. */
diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c
index 4e83d8d8bd..cc66ed8229 100644
--- a/src/qemu/qemu_migration_params.c
+++ b/src/qemu/qemu_migration_params.c
@@ -94,6 +94,7 @@ VIR_ENUM_IMPL(qemuMigrationCapability,
"multifd",
"dirty-bitmaps",
"return-path",
+ "zero-copy-send",
);
@@ -175,6 +176,11 @@ static const qemuMigrationParamsFlagMapItem
qemuMigrationParamsFlagMap[] = {
VIR_MIGRATE_TUNNELLED,
QEMU_MIGRATION_CAP_RETURN_PATH,
QEMU_MIGRATION_SOURCE | QEMU_MIGRATION_DESTINATION},
+
+ {QEMU_MIGRATION_FLAG_REQUIRED,
+ VIR_MIGRATE_ZEROCOPY,
+ QEMU_MIGRATION_CAP_ZERO_COPY_SEND,
+ QEMU_MIGRATION_SOURCE},
};
/* Translation from VIR_MIGRATE_PARAM_* typed parameters to
diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h
index f2f0090343..d1184acded 100644
--- a/src/qemu/qemu_migration_params.h
+++ b/src/qemu/qemu_migration_params.h
@@ -39,6 +39,7 @@ typedef enum {
QEMU_MIGRATION_CAP_MULTIFD,
QEMU_MIGRATION_CAP_BLOCK_DIRTY_BITMAPS,
QEMU_MIGRATION_CAP_RETURN_PATH,
+ QEMU_MIGRATION_CAP_ZERO_COPY_SEND,
QEMU_MIGRATION_CAP_LAST
} qemuMigrationCapability;
--
2.35.1