]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu_migration: Implement VIR_MIGRATE_ZEROCOPY flag
authorJiri Denemark <jdenemar@redhat.com>
Wed, 22 Jun 2022 14:37:31 +0000 (16:37 +0200)
committerJiri Denemark <jdenemar@redhat.com>
Thu, 23 Jun 2022 14:45:39 +0000 (16:45 +0200)
Resolves: https://gitlab.com/libvirt/libvirt/-/issues/306

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
src/qemu/qemu_migration.c
src/qemu/qemu_migration.h
src/qemu/qemu_migration_params.c
src/qemu/qemu_migration_params.h

index e4e0417bdecfef78d95b1779f05065126a9db7cb..2a6b7b7819cf08813f8e8a5e016b5a8ccac6fdc0 100644 (file)
@@ -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) {
index fbc0549b349b96804b79dee1e72eeb49f9b76895..81cc1e91c0f2fb769205c050223591a5a8a1651c 100644 (file)
@@ -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. */
index 4e83d8d8bd390e79211069d5245ce54b41d4372c..cc66ed8229cc85081af5bd39121cfab99bda1822 100644 (file)
@@ -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
index f2f009034313fc0381db35d6ae40d880b114af69..d1184acdedef2a80c21c5b4604c46fa31016e389 100644 (file)
@@ -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;