libvirt assigns affinities to QEMU threads only on domain start,
therefore hot plugged host CPUs cannot be used. Restore the logic from
commit 283e29043423 ("qemu: Allow use of hot plugged host CPUs if no
affinity set"): when the affinity that would be set covers all the
online CPUs anyway, do not set it at all.

qemuProcessGetAllCpuAffinity() already knows when this is the case,
so let it return NULL, which the callers already treat as "leave the
affinity alone".

Fixes: f136b83139c6 ("qemu: Rework setting process affinity")
Signed-off-by: Ilya Leoshkevich <[email protected]>
---
 src/qemu/qemu_process.c | 24 ++++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index b2506edce0..413ec0622d 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -2567,30 +2567,46 @@ qemuProcessDetectIOThreadPIDs(virDomainObj *vm,
 }
 
 
+/**
+ * qemuProcessGetAllCpuAffinity:
+ * @cpumapRet: returned CPU affinity map
+ *
+ * Sets @cpumapRet to the online CPUs minus the isolated ones.
+ *
+ * In case there is nothing to exclude (no isolated CPUs, or no overlap with
+ * online CPUs), sets @cpumapRet to NULL instead, indicating to the caller that
+ * it should not call sched_setaffinity(), which would prevent the usage of
+ * CPUs that are hot plugged later on.
+ *
+ * Returns: 0 on success, -1 on error.
+ */
 static int
 qemuProcessGetAllCpuAffinity(virBitmap **cpumapRet)
 {
     g_autoptr(virBitmap) isolCpus = NULL;
+    g_autoptr(virBitmap) cpumap = NULL;
 
     *cpumapRet = NULL;
 
     if (!virHostCPUHasBitmap())
         return 0;
 
-    if (!(*cpumapRet = virHostCPUGetOnlineBitmap()))
+    if (!(cpumap = virHostCPUGetOnlineBitmap()))
         return -1;
 
     if (virHostCPUGetIsolated(&isolCpus) < 0)
         return -1;
 
-    if (isolCpus) {
+    if (isolCpus && virBitmapOverlaps(cpumap, isolCpus)) {
         g_autofree char *isolCpusStr = virBitmapFormat(isolCpus);
-        g_autofree char *cpumapRetStr = virBitmapFormat(*cpumapRet);
+        g_autofree char *cpumapRetStr = virBitmapFormat(cpumap);
 
         VIR_INFO("Subtracting isolated CPUs %1$s from online CPUs %2$s",
                  isolCpusStr, cpumapRetStr);
 
-        virBitmapSubtract(*cpumapRet, isolCpus);
+        virBitmapSubtract(cpumap, isolCpus);
+
+        *cpumapRet = g_steal_pointer(&cpumap);
     }
 
     return 0;
-- 
2.55.0

Reply via email to