From 35f06623b82d99dd380340eef465394975dd1c80 Mon Sep 17 00:00:00 2001 Message-Id: <35f06623b82d99dd380340eef465394975dd1c80@dist-git> From: Jiri Denemark Date: Wed, 22 Jun 2022 16:37:31 +0200 Subject: [PATCH] qemu_migration: Implement VIR_MIGRATE_ZEROCOPY flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves: https://gitlab.com/libvirt/libvirt/-/issues/306 Signed-off-by: Jiri Denemark Reviewed-by: Ján Tomko (cherry picked from commit d375993ab314a41bca7ef6c846e07afc18c37774) https://bugzilla.redhat.com/show_bug.cgi?id=2089433 Conflicts: src/qemu/qemu_migration.c src/qemu/qemu_migration.h - post-copy recovery not bacported Signed-off-by: Jiri Denemark --- 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 35ad201580..db5163e993 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2366,6 +2366,12 @@ qemuMigrationSrcBeginPhase(virQEMUDriver *driver, return NULL; } + 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)) { @@ -4137,6 +4143,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 b233358a51..6f737f7b4c 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -60,6 +60,7 @@ VIR_MIGRATE_TLS | \ VIR_MIGRATE_PARALLEL | \ VIR_MIGRATE_NON_SHARED_SYNCHRONOUS_WRITES | \ + 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 7b225fdf4b..c985583861 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -96,6 +96,7 @@ VIR_ENUM_IMPL(qemuMigrationCapability, "multifd", "dirty-bitmaps", "return-path", + "zero-copy-send", ); @@ -177,6 +178,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 b4de8dda7b..caa5e47f0f 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -41,6 +41,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