|
|
99cbc7 |
From 539a83390fb4b4b0dd7b029b7dd4ba2a345611cd Mon Sep 17 00:00:00 2001
|
|
|
99cbc7 |
Message-Id: <539a83390fb4b4b0dd7b029b7dd4ba2a345611cd@dist-git>
|
|
|
99cbc7 |
From: Jiri Denemark <jdenemar@redhat.com>
|
|
|
99cbc7 |
Date: Tue, 4 Jun 2019 13:04:33 +0200
|
|
|
99cbc7 |
Subject: [PATCH] qemu: Check TSC frequency before starting QEMU
|
|
|
99cbc7 |
MIME-Version: 1.0
|
|
|
99cbc7 |
Content-Type: text/plain; charset=UTF-8
|
|
|
99cbc7 |
Content-Transfer-Encoding: 8bit
|
|
|
99cbc7 |
|
|
|
99cbc7 |
When migrating a domain with invtsc CPU feature enabled, the TSC
|
|
|
99cbc7 |
frequency of the destination host must match the frequency used when the
|
|
|
99cbc7 |
domain was started on the source host or the destination host has to
|
|
|
99cbc7 |
support TSC scaling.
|
|
|
99cbc7 |
|
|
|
99cbc7 |
If the frequencies do not match and the destination host does not
|
|
|
99cbc7 |
support TSC scaling, QEMU will fail to set the right TSC frequency when
|
|
|
99cbc7 |
starting vCPUs on the destination and thus migration will fail. However,
|
|
|
99cbc7 |
this is quite late since both host might have spent significant time
|
|
|
99cbc7 |
transferring memory and perhaps even storage data.
|
|
|
99cbc7 |
|
|
|
99cbc7 |
By adding the check to libvirt we can let migration fail before any data
|
|
|
99cbc7 |
starts to be sent over. If for some reason libvirt is unable to detect
|
|
|
99cbc7 |
the host's TSC frequency or scaling support, we'll just let QEMU try and
|
|
|
99cbc7 |
the migration will either succeed or fail later.
|
|
|
99cbc7 |
|
|
|
99cbc7 |
Luckily, we mandate TSC frequency to be explicitly set in the domain XML
|
|
|
99cbc7 |
to even allow migration of domains with invtsc. We can just check
|
|
|
99cbc7 |
whether the requested frequency is compatible with the current host
|
|
|
99cbc7 |
before starting QEMU.
|
|
|
99cbc7 |
|
|
|
99cbc7 |
https://bugzilla.redhat.com/show_bug.cgi?id=1641702
|
|
|
99cbc7 |
|
|
|
99cbc7 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
99cbc7 |
(cherry picked from commit 7da62c91f043209e3d40c2dc7655c5e35a4309bf)
|
|
|
99cbc7 |
|
|
|
99cbc7 |
Conflicts:
|
|
|
99cbc7 |
src/qemu/qemu_process.c
|
|
|
99cbc7 |
- qemuProcessStartValidateXML function was removed upstream
|
|
|
99cbc7 |
by commit v4.9.0-89-g91afd53cb8
|
|
|
99cbc7 |
|
|
|
99cbc7 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
99cbc7 |
Message-Id: <f5fcbf9d5afc4e156d1d2c888dc360d06bb29a1a.1559646067.git.jdenemar@redhat.com>
|
|
|
99cbc7 |
Reviewed-by: Ján Tomko <jtomko@redhat.com>
|
|
|
99cbc7 |
---
|
|
|
99cbc7 |
src/qemu/qemu_process.c | 53 +++++++++++++++++++++++++++++++++++++++++
|
|
|
99cbc7 |
1 file changed, 53 insertions(+)
|
|
|
99cbc7 |
|
|
|
99cbc7 |
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
|
|
|
99cbc7 |
index 2795796166..7f70d79566 100644
|
|
|
99cbc7 |
--- a/src/qemu/qemu_process.c
|
|
|
99cbc7 |
+++ b/src/qemu/qemu_process.c
|
|
|
99cbc7 |
@@ -5181,6 +5181,56 @@ qemuProcessStartValidateXML(virQEMUDriverPtr driver,
|
|
|
99cbc7 |
}
|
|
|
99cbc7 |
|
|
|
99cbc7 |
|
|
|
99cbc7 |
+static int
|
|
|
99cbc7 |
+qemuProcessStartValidateTSC(virDomainObjPtr vm,
|
|
|
99cbc7 |
+ virCapsPtr caps)
|
|
|
99cbc7 |
+{
|
|
|
99cbc7 |
+ size_t i;
|
|
|
99cbc7 |
+ unsigned long long freq = 0;
|
|
|
99cbc7 |
+ virHostCPUTscInfoPtr tsc;
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
+ for (i = 0; i < vm->def->clock.ntimers; i++) {
|
|
|
99cbc7 |
+ virDomainTimerDefPtr timer = vm->def->clock.timers[i];
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
+ if (timer->name == VIR_DOMAIN_TIMER_NAME_TSC &&
|
|
|
99cbc7 |
+ timer->frequency > 0) {
|
|
|
99cbc7 |
+ freq = timer->frequency;
|
|
|
99cbc7 |
+ break;
|
|
|
99cbc7 |
+ }
|
|
|
99cbc7 |
+ }
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
+ if (freq == 0)
|
|
|
99cbc7 |
+ return 0;
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
+ VIR_DEBUG("Requested TSC frequency %llu Hz", freq);
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
+ if (!caps->host.cpu || !caps->host.cpu->tsc) {
|
|
|
99cbc7 |
+ VIR_DEBUG("Host TSC frequency could not be probed");
|
|
|
99cbc7 |
+ return 0;
|
|
|
99cbc7 |
+ }
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
+ tsc = caps->host.cpu->tsc;
|
|
|
99cbc7 |
+ VIR_DEBUG("Host TSC frequency %llu Hz, scaling %s",
|
|
|
99cbc7 |
+ tsc->frequency, virTristateBoolTypeToString(tsc->scaling));
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
+ if (freq == tsc->frequency || tsc->scaling == VIR_TRISTATE_BOOL_YES)
|
|
|
99cbc7 |
+ return 0;
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
+ if (tsc->scaling == VIR_TRISTATE_BOOL_ABSENT) {
|
|
|
99cbc7 |
+ VIR_DEBUG("TSC frequencies do not match and scaling support is "
|
|
|
99cbc7 |
+ "unknown, QEMU will try and possibly fail later");
|
|
|
99cbc7 |
+ return 0;
|
|
|
99cbc7 |
+ }
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
99cbc7 |
+ _("Requested TSC frequency %llu Hz does not match "
|
|
|
99cbc7 |
+ "host (%llu Hz) and TSC scaling is not supported "
|
|
|
99cbc7 |
+ "by the host CPU"),
|
|
|
99cbc7 |
+ freq, tsc->frequency);
|
|
|
99cbc7 |
+ return -1;
|
|
|
99cbc7 |
+}
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
/**
|
|
|
99cbc7 |
* qemuProcessStartValidate:
|
|
|
99cbc7 |
* @vm: domain object
|
|
|
99cbc7 |
@@ -5241,6 +5291,9 @@ qemuProcessStartValidate(virQEMUDriverPtr driver,
|
|
|
99cbc7 |
if (qemuProcessStartValidateDisks(vm, qemuCaps) < 0)
|
|
|
99cbc7 |
return -1;
|
|
|
99cbc7 |
|
|
|
99cbc7 |
+ if (qemuProcessStartValidateTSC(vm, caps) < 0)
|
|
|
99cbc7 |
+ return -1;
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
VIR_DEBUG("Checking for any possible (non-fatal) issues");
|
|
|
99cbc7 |
|
|
|
99cbc7 |
qemuProcessStartWarnShmem(vm);
|
|
|
99cbc7 |
--
|
|
|
99cbc7 |
2.21.0
|
|
|
99cbc7 |
|