Although QMP returns info about vCPU threads in TCG mode, the
data it returns is mostly lies. Only the first vCPU has a valid
thread_id returned. The thread_id given for the other vCPUs is
in fact the main emulator thread. All vCPUs actually run under
the same thread in TCG mode.
Our vCPU pinning code is not at all able to cope with this
so if you try to set CPU affinity per-vCPU you end up with
wierd errors
error: Failed to start domain instance-00000007
error: cannot set CPU affinity on process 24365: Invalid argument
Since few people will care about the performance of TCG with
strict CPU pinning, lets just disable that for now, so we get
a clear error message
error: Failed to start domain instance-00000007
error: Requested operation is not valid: cpu affinity is not supported
---
src/qemu/qemu_process.c | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index b067f18..e2ccc4e 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -2231,6 +2231,40 @@ qemuProcessDetectVcpuPIDs(virQEMUDriverPtr driver,
int ncpupids;
qemuDomainObjPrivatePtr priv = vm->privateData;
+ /*
+ * Current QEMU *can* report info about host threads mapped
+ * to vCPUs, but it is not in a manner we can correctly
+ * deal with. The TCG CPU emulation does have a separate vCPU
+ * thread, but it runs every vCPU in that same thread. So it
+ * is impossible to setup different affinity per thread.
+ *
+ * What's more the 'query-cpus' command returns bizarre
+ * data for the threads. It gives the TCG thread for the
+ * vCPU 0, but for vCPUs 1-> N, it actually replies with
+ * the main process thread ID.
+ *
+ * The result is that when we try to set affinity for
+ * vCPU 1, it will actually change the affinity of the
+ * emulator thread :-( When you try to set affinity for
+ * vCPUs 2, 3.... it will fail if the affinity was
+ * different from vCPU 1.
+ *
+ * We *could* allow vcpu pinning with TCG, if we made the
+ * restriction that all vCPUs had the same mask. This would
+ * at least let us separate emulator from vCPUs threads, as
+ * we do for KVM. It would need some changes to our cgroups
+ * CPU layout though, and error reporting for the config
+ * restrictions.
+ *
+ * Just disable CPU pinning with TCG until someone wants
+ * to try to do this hard work.
+ */
+ if (vm->def->virtType == VIR_DOMAIN_VIRT_QEMU) {
+ priv->nvcpupids = 0;
+ priv->vcpupids = NULL;
+ return 0;
+ }
+
if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
return -1;
/* failure to get the VCPU<-> PID mapping or to execute the query
--
2.1.0