|
|
6ae9ed |
From 4d614a11dd3164c63a5e28fdeff8b5f196a7ee18 Mon Sep 17 00:00:00 2001
|
|
|
6ae9ed |
Message-Id: <4d614a11dd3164c63a5e28fdeff8b5f196a7ee18@dist-git>
|
|
|
6ae9ed |
From: Peter Krempa <pkrempa@redhat.com>
|
|
|
6ae9ed |
Date: Wed, 24 Aug 2016 16:11:30 -0400
|
|
|
6ae9ed |
Subject: [PATCH] qemu: domain: Extract cpu-hotplug related data
|
|
|
6ae9ed |
|
|
|
6ae9ed |
https://bugzilla.redhat.com/show_bug.cgi?id=1097930
|
|
|
6ae9ed |
https://bugzilla.redhat.com/show_bug.cgi?id=1224341
|
|
|
6ae9ed |
|
|
|
6ae9ed |
Now that the monitor code gathers all the data we can extract it to
|
|
|
6ae9ed |
relevant places either in the definition or the private data of a vcpu.
|
|
|
6ae9ed |
|
|
|
6ae9ed |
As only thread id is broken for TCG guests we may extract the rest of
|
|
|
6ae9ed |
the data and just skip assigning of the thread id. In case where qemu
|
|
|
6ae9ed |
would allow cpu hotplug in TCG mode this will make it work eventually.
|
|
|
6ae9ed |
|
|
|
6ae9ed |
(cherry picked from commit 6b4a23ff6c78bfc901a3c1a33460423ff702461f)
|
|
|
6ae9ed |
---
|
|
|
6ae9ed |
src/qemu/qemu_domain.c | 90 ++++++++++++++++++++++++++++++++------------------
|
|
|
6ae9ed |
src/qemu/qemu_domain.h | 10 ++++++
|
|
|
6ae9ed |
2 files changed, 67 insertions(+), 33 deletions(-)
|
|
|
6ae9ed |
|
|
|
6ae9ed |
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
|
|
|
6ae9ed |
index ebd0d9e..259fd79 100644
|
|
|
6ae9ed |
--- a/src/qemu/qemu_domain.c
|
|
|
6ae9ed |
+++ b/src/qemu/qemu_domain.c
|
|
|
6ae9ed |
@@ -847,8 +847,12 @@ qemuDomainVcpuPrivateNew(void)
|
|
|
6ae9ed |
|
|
|
6ae9ed |
|
|
|
6ae9ed |
static void
|
|
|
6ae9ed |
-qemuDomainVcpuPrivateDispose(void *obj ATTRIBUTE_UNUSED)
|
|
|
6ae9ed |
+qemuDomainVcpuPrivateDispose(void *obj)
|
|
|
6ae9ed |
{
|
|
|
6ae9ed |
+ qemuDomainVcpuPrivatePtr priv = obj;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ VIR_FREE(priv->type);
|
|
|
6ae9ed |
+ VIR_FREE(priv->alias);
|
|
|
6ae9ed |
return;
|
|
|
6ae9ed |
}
|
|
|
6ae9ed |
|
|
|
6ae9ed |
@@ -5696,6 +5700,15 @@ qemuDomainValidateVcpuInfo(virDomainObjPtr vm)
|
|
|
6ae9ed |
}
|
|
|
6ae9ed |
|
|
|
6ae9ed |
|
|
|
6ae9ed |
+bool
|
|
|
6ae9ed |
+qemuDomainSupportsNewVcpuHotplug(virDomainObjPtr vm)
|
|
|
6ae9ed |
+{
|
|
|
6ae9ed |
+ qemuDomainObjPrivatePtr priv = vm->privateData;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ return virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_QUERY_HOTPLUGGABLE_CPUS);
|
|
|
6ae9ed |
+}
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
/**
|
|
|
6ae9ed |
* qemuDomainRefreshVcpuInfo:
|
|
|
6ae9ed |
* @driver: qemu driver data
|
|
|
6ae9ed |
@@ -5717,44 +5730,16 @@ qemuDomainRefreshVcpuInfo(virQEMUDriverPtr driver,
|
|
|
6ae9ed |
qemuMonitorCPUInfoPtr info = NULL;
|
|
|
6ae9ed |
size_t maxvcpus = virDomainDefGetVcpusMax(vm->def);
|
|
|
6ae9ed |
size_t i;
|
|
|
6ae9ed |
+ bool hotplug;
|
|
|
6ae9ed |
int rc;
|
|
|
6ae9ed |
int ret = -1;
|
|
|
6ae9ed |
|
|
|
6ae9ed |
- /*
|
|
|
6ae9ed |
- * Current QEMU *can* report info about host threads mapped
|
|
|
6ae9ed |
- * to vCPUs, but it is not in a manner we can correctly
|
|
|
6ae9ed |
- * deal with. The TCG CPU emulation does have a separate vCPU
|
|
|
6ae9ed |
- * thread, but it runs every vCPU in that same thread. So it
|
|
|
6ae9ed |
- * is impossible to setup different affinity per thread.
|
|
|
6ae9ed |
- *
|
|
|
6ae9ed |
- * What's more the 'query-cpus' command returns bizarre
|
|
|
6ae9ed |
- * data for the threads. It gives the TCG thread for the
|
|
|
6ae9ed |
- * vCPU 0, but for vCPUs 1-> N, it actually replies with
|
|
|
6ae9ed |
- * the main process thread ID.
|
|
|
6ae9ed |
- *
|
|
|
6ae9ed |
- * The result is that when we try to set affinity for
|
|
|
6ae9ed |
- * vCPU 1, it will actually change the affinity of the
|
|
|
6ae9ed |
- * emulator thread :-( When you try to set affinity for
|
|
|
6ae9ed |
- * vCPUs 2, 3.... it will fail if the affinity was
|
|
|
6ae9ed |
- * different from vCPU 1.
|
|
|
6ae9ed |
- *
|
|
|
6ae9ed |
- * We *could* allow vcpu pinning with TCG, if we made the
|
|
|
6ae9ed |
- * restriction that all vCPUs had the same mask. This would
|
|
|
6ae9ed |
- * at least let us separate emulator from vCPUs threads, as
|
|
|
6ae9ed |
- * we do for KVM. It would need some changes to our cgroups
|
|
|
6ae9ed |
- * CPU layout though, and error reporting for the config
|
|
|
6ae9ed |
- * restrictions.
|
|
|
6ae9ed |
- *
|
|
|
6ae9ed |
- * Just disable CPU pinning with TCG until someone wants
|
|
|
6ae9ed |
- * to try to do this hard work.
|
|
|
6ae9ed |
- */
|
|
|
6ae9ed |
- if (vm->def->virtType == VIR_DOMAIN_VIRT_QEMU)
|
|
|
6ae9ed |
- return 0;
|
|
|
6ae9ed |
+ hotplug = qemuDomainSupportsNewVcpuHotplug(vm);
|
|
|
6ae9ed |
|
|
|
6ae9ed |
if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
|
|
|
6ae9ed |
return -1;
|
|
|
6ae9ed |
|
|
|
6ae9ed |
- rc = qemuMonitorGetCPUInfo(qemuDomainGetMonitor(vm), &info, maxvcpus, false);
|
|
|
6ae9ed |
+ rc = qemuMonitorGetCPUInfo(qemuDomainGetMonitor(vm), &info, maxvcpus, hotplug);
|
|
|
6ae9ed |
|
|
|
6ae9ed |
if (qemuDomainObjExitMonitor(driver, vm) < 0)
|
|
|
6ae9ed |
goto cleanup;
|
|
|
6ae9ed |
@@ -5766,7 +5751,46 @@ qemuDomainRefreshVcpuInfo(virQEMUDriverPtr driver,
|
|
|
6ae9ed |
vcpu = virDomainDefGetVcpu(vm->def, i);
|
|
|
6ae9ed |
vcpupriv = QEMU_DOMAIN_VCPU_PRIVATE(vcpu);
|
|
|
6ae9ed |
|
|
|
6ae9ed |
- vcpupriv->tid = info[i].tid;
|
|
|
6ae9ed |
+ /*
|
|
|
6ae9ed |
+ * Current QEMU *can* report info about host threads mapped
|
|
|
6ae9ed |
+ * to vCPUs, but it is not in a manner we can correctly
|
|
|
6ae9ed |
+ * deal with. The TCG CPU emulation does have a separate vCPU
|
|
|
6ae9ed |
+ * thread, but it runs every vCPU in that same thread. So it
|
|
|
6ae9ed |
+ * is impossible to setup different affinity per thread.
|
|
|
6ae9ed |
+ *
|
|
|
6ae9ed |
+ * What's more the 'query-cpus' command returns bizarre
|
|
|
6ae9ed |
+ * data for the threads. It gives the TCG thread for the
|
|
|
6ae9ed |
+ * vCPU 0, but for vCPUs 1-> N, it actually replies with
|
|
|
6ae9ed |
+ * the main process thread ID.
|
|
|
6ae9ed |
+ *
|
|
|
6ae9ed |
+ * The result is that when we try to set affinity for
|
|
|
6ae9ed |
+ * vCPU 1, it will actually change the affinity of the
|
|
|
6ae9ed |
+ * emulator thread :-( When you try to set affinity for
|
|
|
6ae9ed |
+ * vCPUs 2, 3.... it will fail if the affinity was
|
|
|
6ae9ed |
+ * different from vCPU 1.
|
|
|
6ae9ed |
+ *
|
|
|
6ae9ed |
+ * We *could* allow vcpu pinning with TCG, if we made the
|
|
|
6ae9ed |
+ * restriction that all vCPUs had the same mask. This would
|
|
|
6ae9ed |
+ * at least let us separate emulator from vCPUs threads, as
|
|
|
6ae9ed |
+ * we do for KVM. It would need some changes to our cgroups
|
|
|
6ae9ed |
+ * CPU layout though, and error reporting for the config
|
|
|
6ae9ed |
+ * restrictions.
|
|
|
6ae9ed |
+ *
|
|
|
6ae9ed |
+ * Just disable CPU pinning with TCG until someone wants
|
|
|
6ae9ed |
+ * to try to do this hard work.
|
|
|
6ae9ed |
+ */
|
|
|
6ae9ed |
+ if (vm->def->virtType != VIR_DOMAIN_VIRT_QEMU)
|
|
|
6ae9ed |
+ vcpupriv->tid = info[i].tid;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ vcpupriv->socket_id = info[i].socket_id;
|
|
|
6ae9ed |
+ vcpupriv->core_id = info[i].core_id;
|
|
|
6ae9ed |
+ vcpupriv->thread_id = info[i].thread_id;
|
|
|
6ae9ed |
+ vcpupriv->vcpus = info[i].vcpus;
|
|
|
6ae9ed |
+ VIR_FREE(vcpupriv->type);
|
|
|
6ae9ed |
+ VIR_STEAL_PTR(vcpupriv->type, info[i].type);
|
|
|
6ae9ed |
+ VIR_FREE(vcpupriv->alias);
|
|
|
6ae9ed |
+ VIR_STEAL_PTR(vcpupriv->alias, info[i].alias);
|
|
|
6ae9ed |
+ vcpupriv->enable_id = info[i].id;
|
|
|
6ae9ed |
}
|
|
|
6ae9ed |
|
|
|
6ae9ed |
ret = 0;
|
|
|
6ae9ed |
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
|
|
|
6ae9ed |
index a7176c4..c3ae169 100644
|
|
|
6ae9ed |
--- a/src/qemu/qemu_domain.h
|
|
|
6ae9ed |
+++ b/src/qemu/qemu_domain.h
|
|
|
6ae9ed |
@@ -317,6 +317,15 @@ struct _qemuDomainVcpuPrivate {
|
|
|
6ae9ed |
virObject parent;
|
|
|
6ae9ed |
|
|
|
6ae9ed |
pid_t tid; /* vcpu thread id */
|
|
|
6ae9ed |
+ int enable_id; /* order in which the vcpus were enabled in qemu */
|
|
|
6ae9ed |
+ char *alias;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ /* information for hotpluggable cpus */
|
|
|
6ae9ed |
+ char *type;
|
|
|
6ae9ed |
+ int socket_id;
|
|
|
6ae9ed |
+ int core_id;
|
|
|
6ae9ed |
+ int thread_id;
|
|
|
6ae9ed |
+ int vcpus;
|
|
|
6ae9ed |
};
|
|
|
6ae9ed |
|
|
|
6ae9ed |
# define QEMU_DOMAIN_VCPU_PRIVATE(vcpu) \
|
|
|
6ae9ed |
@@ -647,6 +656,7 @@ int qemuDomainDefValidateMemoryHotplug(const virDomainDef *def,
|
|
|
6ae9ed |
virQEMUCapsPtr qemuCaps,
|
|
|
6ae9ed |
const virDomainMemoryDef *mem);
|
|
|
6ae9ed |
|
|
|
6ae9ed |
+bool qemuDomainSupportsNewVcpuHotplug(virDomainObjPtr vm);
|
|
|
6ae9ed |
bool qemuDomainHasVcpuPids(virDomainObjPtr vm);
|
|
|
6ae9ed |
pid_t qemuDomainGetVcpuPid(virDomainObjPtr vm, unsigned int vcpuid);
|
|
|
6ae9ed |
int qemuDomainValidateVcpuInfo(virDomainObjPtr vm);
|
|
|
6ae9ed |
--
|
|
|
6ae9ed |
2.10.0
|
|
|
6ae9ed |
|