[libvirt] [PATCH 6/8] qemu: Set cpuset.cpus for domain process

Osier Yang jyang at redhat.com
Thu May 9 10:28:31 UTC 2013


Hi, Doug

Do you think if this fixes your problem?

https://www.redhat.com/archives/libvirt-users/2013-January/msg00071.html

Osier
On 09/05/13 18:22, Osier Yang wrote:
> When either "cpuset" of <vcpu> is specified, or the "placement" of
> <vcpu> is "auto", only setting the cpuset.mems might cause the guest
> starting to fail. E.g. ("placement" of both <vcpu> and <numatune> is
> "auto"):
>
> 1) Related XMLs
>    <vcpu placement='auto'>4</vcpu>
>    <numatune>
>      <memory mode='strict' placement='auto'/>
>    </numatune>
>
> 2) Host NUMA topology
>    % numactl --hardware
>    available: 8 nodes (0-7)
>    node 0 cpus: 0 4 8 12 16 20 24 28
>    node 0 size: 16374 MB
>    node 0 free: 11899 MB
>    node 1 cpus: 32 36 40 44 48 52 56 60
>    node 1 size: 16384 MB
>    node 1 free: 15318 MB
>    node 2 cpus: 2 6 10 14 18 22 26 30
>    node 2 size: 16384 MB
>    node 2 free: 15766 MB
>    node 3 cpus: 34 38 42 46 50 54 58 62
>    node 3 size: 16384 MB
>    node 3 free: 15347 MB
>    node 4 cpus: 3 7 11 15 19 23 27 31
>    node 4 size: 16384 MB
>    node 4 free: 15041 MB
>    node 5 cpus: 35 39 43 47 51 55 59 63
>    node 5 size: 16384 MB
>    node 5 free: 15202 MB
>    node 6 cpus: 1 5 9 13 17 21 25 29
>    node 6 size: 16384 MB
>    node 6 free: 15197 MB
>    node 7 cpus: 33 37 41 45 49 53 57 61
>    node 7 size: 16368 MB
>    node 7 free: 15669 MB
>
> 4) cpuset.cpus will be set as: (from debug log)
>
> 2013-05-09 16:50:17.296+0000: 417: debug : virCgroupSetValueStr:331 :
> Set value '/sys/fs/cgroup/cpuset/libvirt/qemu/toy/cpuset.cpus'
> to '0-63'
>
> 5) The advisory nodeset got from querying numad (from debug log)
>
> 2013-05-09 16:50:17.295+0000: 417: debug : qemuProcessStart:3614 :
> Nodeset returned from numad: 1
>
> 6) cpuset.mems will be set as: (from debug log)
>
> 2013-05-09 16:50:17.296+0000: 417: debug : virCgroupSetValueStr:331 :
> Set value '/sys/fs/cgroup/cpuset/libvirt/qemu/toy/cpuset.mems'
> to '0-7'
>
> I.E, the domain process's memory is restricted on the first NUMA node,
> however, it can use all of the CPUs, which will very likely cause the
> domain process to fail to start because of the kernel fails to allocate
> memory with the possible mismatching between CPU nodes and memory nodes.
>
> % tail -n 20 /var/log/libvirt/qemu/toy.log
> ...
> 2013-05-09 05:53:32.972+0000: 7318: debug : virCommandHandshakeChild:377 :
> Handshake with parent is done
> char device redirected to /dev/pts/2 (label charserial0)
> kvm_init_vcpu failed: Cannot allocate memory
> ...
>
> ---
>   src/qemu/qemu_cgroup.c | 39 +++++++++++++++++++++++++++++++++------
>   1 file changed, 33 insertions(+), 6 deletions(-)
>
> diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
> index 0e00b47..33eebd7 100644
> --- a/src/qemu/qemu_cgroup.c
> +++ b/src/qemu/qemu_cgroup.c
> @@ -589,7 +589,8 @@ qemuSetupCpusetCgroup(virDomainObjPtr vm,
>                         virBitmapPtr nodemask)
>   {
>       qemuDomainObjPrivatePtr priv = vm->privateData;
> -    char *mask = NULL;
> +    char *mem_mask = NULL;
> +    char *cpu_mask = NULL;
>       int rc;
>       int ret = -1;
>   
> @@ -603,17 +604,17 @@ qemuSetupCpusetCgroup(virDomainObjPtr vm,
>   
>           if (vm->def->numatune.memory.placement_mode ==
>               VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO)
> -            mask = virBitmapFormat(nodemask);
> +            mem_mask = virBitmapFormat(nodemask);
>           else
> -            mask = virBitmapFormat(vm->def->numatune.memory.nodemask);
> +            mem_mask = virBitmapFormat(vm->def->numatune.memory.nodemask);
>   
> -        if (!mask) {
> +        if (!mem_mask) {
>               virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
>                              _("failed to convert memory nodemask"));
>               goto cleanup;
>           }
>   
> -        rc = virCgroupSetCpusetMems(priv->cgroup, mask);
> +        rc = virCgroupSetCpusetMems(priv->cgroup, mem_mask);
>   
>           if (rc != 0) {
>               virReportSystemError(-rc,
> @@ -623,9 +624,35 @@ qemuSetupCpusetCgroup(virDomainObjPtr vm,
>           }
>       }
>   
> +    if (vm->def->cpumask ||
> +        (vm->def->placement_mode ==
> +         VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO)) {
> +        if (vm->def->placement_mode ==
> +            VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO)
> +            cpu_mask = virBitmapFormat(nodemask);
> +        else
> +            cpu_mask = virBitmapFormat(vm->def->cpumask);
> +
> +        if (!cpu_mask) {
> +            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                           _("failed to convert memory nodemask"));
> +            goto cleanup;
> +        }
> +
> +        rc = virCgroupSetCpusetCpus(priv->cgroup, cpu_mask);
> +
> +        if (rc != 0) {
> +            virReportSystemError(-rc,
> +                                 _("Unable to set cpuset.cpus for domain %s"),
> +                                 vm->def->name);
> +            goto cleanup;
> +        }
> +    }
> +
>       ret = 0;
>   cleanup:
> -    VIR_FREE(mask);
> +    VIR_FREE(mem_mask);
> +    VIR_FREE(cpu_mask);
>       return ret;
>   }
>   




More information about the libvir-list mailing list