[libvirt] [PATCH] Fix QEMU cpu affinity at startup to include all threads

Daniel Veillard veillard at redhat.com
Fri Mar 26 15:34:41 UTC 2010


On Thu, Mar 25, 2010 at 05:27:16PM +0000, Daniel P. Berrange wrote:
> The QEMU cpu affinity is used in NUMA scenarios to ensure that
> guest memory is allocated from a specific node. Normally memory
> is allocate on demand in vCPU threads, but when using hugepages
> the initial thread leader allocates memory upfront. libvirt was
> not setting affinity of the thread leader, or I/O threads. This
> patch changes the code to set the process affinity in between
> the fork()/exec() of QEMU. This ensures that every single QEMU
> thread gets the affinity
> 
> * src/qemu/qemu_driver.c: Set affinity on entire QEMU process
>   at startup
> ---
>  src/qemu/qemu_driver.c |   29 ++++++++++++++++-------------
>  1 files changed, 16 insertions(+), 13 deletions(-)
> 
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 257f914..2598deb 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -1701,6 +1701,9 @@ qemuDetectVcpuPIDs(struct qemud_driver *driver,
>      return 0;
>  }
>  
> +/*
> + * To be run between fork/exec of QEMU only
> + */
>  static int
>  qemudInitCpuAffinity(virDomainObjPtr vm)
>  {
> @@ -1708,7 +1711,8 @@ qemudInitCpuAffinity(virDomainObjPtr vm)
>      virNodeInfo nodeinfo;
>      unsigned char *cpumap;
>      int cpumaplen;
> -    qemuDomainObjPrivatePtr priv = vm->privateData;
> +
> +    DEBUG0("Setting CPU affinity");
>  
>      if (nodeGetInfo(NULL, &nodeinfo) < 0)
>          return -1;
> @@ -1740,14 +1744,14 @@ qemudInitCpuAffinity(virDomainObjPtr vm)
>              VIR_USE_CPU(cpumap, i);
>      }
>  
> -    /* The XML config only gives a per-VM affinity, so we apply
> -     * the same mapping to all vCPUs */
> -    for (i = 0 ; i < priv->nvcpupids ; i++) {
> -        if (virProcessInfoSetAffinity(priv->vcpupids[i],
> -                                      cpumap, cpumaplen, maxcpu) < 0) {
> -            VIR_FREE(cpumap);
> -            return -1;
> -        }
> +    /* We are assuming we are running between fork/exec of QEMU, so
> +     * that getpid() gives the QEMU process ID and we know that
> +     * no threads are running.
> +     */
> +    if (virProcessInfoSetAffinity(getpid(),
> +                                  cpumap, cpumaplen, maxcpu) < 0) {
> +        VIR_FREE(cpumap);
> +        return -1;
>      }
>      VIR_FREE(cpumap);
>  
> @@ -2653,6 +2657,9 @@ struct qemudHookData {
>  static int qemudSecurityHook(void *data) {
>      struct qemudHookData *h = data;
>  
> +    if (qemudInitCpuAffinity(h->vm) < 0)
> +        return -1;
> +
>      if (qemuAddToCgroup(h->driver, h->vm->def) < 0)
>          return -1;
>  
> @@ -2943,10 +2950,6 @@ static int qemudStartVMDaemon(virConnectPtr conn,
>      if (qemuDetectVcpuPIDs(driver, vm) < 0)
>          goto abort;
>  
> -    DEBUG0("Setting CPU affinity");
> -    if (qemudInitCpuAffinity(vm) < 0)
> -        goto abort;
> -
>      DEBUG0("Setting any required VM passwords");
>      if (qemuInitPasswords(conn, driver, vm, qemuCmdFlags) < 0)
>          goto abort;

  ACK,

Daniel

-- 
Daniel Veillard      | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
daniel at veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/




More information about the libvir-list mailing list