[libvirt] [PATCH v2] Get the maxvcpus from both the qemuCaps and /dev/kvm

Shivaprasad G Bhat shivaprasadbhat at gmail.com
Wed May 4 12:34:12 UTC 2016


For some archs and machines, the maxvcpus defined in the kernel can be different
from the qemu-caps maxvcpus. Just reporting the kernel defined maxvcpus is not
be sufficient. virsh domacapabilities and virsh maxvcpus --type kvm return
different maxvcpus values and is confusing as to know what actually works.
The minimum of the two values is what actually works.

For example on PPC64, the KVM_MAX_VCPUS is defined to be 1024 in kernel
where as qemu has MAX_CPUMASK_BITS defined at 255 in include/sysemu/sysemu.h.
The guest can go upto 256 vcpus here.

Signed-off-by: Shivaprasad G Bhat <sbhat at linux.vnet.ibm.com>
---
 src/qemu/qemu_driver.c |   27 ++++++++++++++++++++++++---
 1 file changed, 24 insertions(+), 3 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 3d0c7c8..2716af8 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1255,10 +1255,31 @@ static int qemuConnectIsAlive(virConnectPtr conn ATTRIBUTE_UNUSED)
 
 
 static int
-kvmGetMaxVCPUs(void)
+kvmGetMaxVCPUs(virConnectPtr conn)
 {
     int fd;
     int ret;
+    int qemuCapsMaxVcpus = 0;
+    virArch arch = virArchFromHost();
+    virQEMUCapsPtr qemuCaps = NULL;
+    virQEMUDriverPtr driver = conn->privateData;
+    const char *machine;
+
+    if (!(qemuCaps = virQEMUCapsCacheLookupByArch(driver->qemuCapsCache,
+                                                      arch))) {
+        virReportError(VIR_ERR_INVALID_ARG,
+                       _("unable to find any emulator to serve '%s' "
+                         "architecture"), virArchToString(arch));
+        return -1;
+    }
+
+    if (!(machine = virQEMUCapsGetDefaultMachine(qemuCaps))) {
+        virObjectUnref(qemuCaps);
+        return -1;
+    }
+
+    qemuCapsMaxVcpus = virQEMUCapsGetMachineMaxCpus(qemuCaps, machine);
+    virObjectUnref(qemuCaps);
 
     if ((fd = open(KVM_DEVICE, O_RDONLY)) < 0) {
         virReportSystemError(errno, _("Unable to open %s"), KVM_DEVICE);
@@ -1282,7 +1303,7 @@ kvmGetMaxVCPUs(void)
 
  cleanup:
     VIR_FORCE_CLOSE(fd);
-    return ret;
+    return ret > qemuCapsMaxVcpus ? qemuCapsMaxVcpus : ret;
 }
 
 
@@ -1323,7 +1344,7 @@ qemuConnectGetMaxVcpus(virConnectPtr conn ATTRIBUTE_UNUSED, const char *type)
         return 16;
 
     if (STRCASEEQ(type, "kvm"))
-        return kvmGetMaxVCPUs();
+        return kvmGetMaxVCPUs(conn);
 
     if (STRCASEEQ(type, "kqemu"))
         return 1;




More information about the libvir-list mailing list