[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

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



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 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;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]