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

Cole Robinson crobinso at redhat.com
Wed May 4 14:12:24 UTC 2016


On 05/04/2016 08:34 AM, Shivaprasad G Bhat wrote:
> 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(-)
> 

You'll also need to extend the virConnectGetMaxVcpus doc string in
src/libvirt-host.c to indicate it may limit the reported CPUs based on host
arch and default machine type.

Additionally, there's also virDomainGetMaxVcpus which is just
virConnectGetMaxVcpus(def->type), however we should extend the way that is
handled internally to also abide the domain's arch and machine type in this case.

One comment below:

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

You can use MIN() here

Thanks,
Cole




More information about the libvir-list mailing list