[libvirt] [PATCHv2] Add cputune support to libxl driver

Jim Fehlig jfehlig at novell.com
Mon Apr 18 18:14:28 UTC 2011


Markus Groß wrote:
> Here is a new version of this patch:
> https://www.redhat.com/archives/libvir-list/2011-April/msg00337.html
>
> v2:
>   - store the cputune info for the whole runtime of the domain 
>   - remove cputune info when domain is destroyed
>
> The nodeGetInfo code had to be moved into a helper
> function to reuse it without a virConnectPtr.
> ---
>  src/libxl/libxl_driver.c |  159 +++++++++++++++++++++++++++++++++++-----------
>  1 files changed, 122 insertions(+), 37 deletions(-)
>   

I tested all sorts of combinations of starting domains (hvm and pv),
pinning vcpus, shutting down domains, and restarting libvirt - looks
good!  Thanks Markus.

ACK and pushed.

Regards,
Jim

> diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
> index 3040914..247d78e 100644
> --- a/src/libxl/libxl_driver.c
> +++ b/src/libxl/libxl_driver.c
> @@ -199,6 +199,46 @@ libxlAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED,
>          virDomainObjUnlock(vm);
>  }
>  
> +static int
> +libxlDoNodeGetInfo(libxlDriverPrivatePtr driver, virNodeInfoPtr info)
> +{
> +    libxl_physinfo phy_info;
> +    const libxl_version_info* ver_info;
> +    struct utsname utsname;
> +
> +    if (libxl_get_physinfo(&driver->ctx, &phy_info)) {
> +        libxlError(VIR_ERR_INTERNAL_ERROR,
> +                   _("libxl_get_physinfo_info failed"));
> +        return -1;
> +    }
> +
> +    if ((ver_info = libxl_get_version_info(&driver->ctx)) == NULL) {
> +        libxlError(VIR_ERR_INTERNAL_ERROR,
> +                   _("libxl_get_version_info failed"));
> +        return -1;
> +    }
> +
> +    uname(&utsname);
> +    if (virStrncpy(info->model,
> +                   utsname.machine,
> +                   strlen(utsname.machine),
> +                   sizeof(info->model)) == NULL) {
> +        libxlError(VIR_ERR_INTERNAL_ERROR,
> +                   _("machine type %s too big for destination"),
> +                   utsname.machine);
> +        return -1;
> +    }
> +
> +    info->memory = phy_info.total_pages * (ver_info->pagesize / 1024);
> +    info->cpus = phy_info.nr_cpus;
> +    info->nodes = phy_info.nr_nodes;
> +    info->cores = phy_info.cores_per_socket;
> +    info->threads = phy_info.threads_per_core;
> +    info->sockets = 1;
> +    info->mhz = phy_info.cpu_khz / 1000;
> +    return 0;
> +}
> +
>  /*
>   * Cleanup function for domain that has reached shutoff state.
>   *
> @@ -210,6 +250,7 @@ libxlVmCleanup(libxlDriverPrivatePtr driver, virDomainObjPtr vm)
>      libxlDomainObjPrivatePtr priv = vm->privateData;
>      int vnc_port;
>      char *file;
> +    int i;
>  
>      if (priv->eventHdl >= 0) {
>          virEventRemoveHandle(priv->eventHdl);
> @@ -238,6 +279,16 @@ libxlVmCleanup(libxlDriverPrivatePtr driver, virDomainObjPtr vm)
>          }
>      }
>  
> +    /* Remove any cputune settings */
> +    if (vm->def->cputune.nvcpupin) {
> +        for (i = 0; i < vm->def->cputune.nvcpupin; ++i) {
> +            VIR_FREE(vm->def->cputune.vcpupin[i]->cpumask);
> +            VIR_FREE(vm->def->cputune.vcpupin[i]);
> +        }
> +        VIR_FREE(vm->def->cputune.vcpupin);
> +        vm->def->cputune.nvcpupin = 0;
> +    }
> +
>      if (virAsprintf(&file, "%s/%s.xml", driver->stateDir, vm->def->name) > 0) {
>          if (unlink(file) < 0 && errno != ENOENT && errno != ENOTDIR)
>              VIR_DEBUG("Failed to remove domain XML for %s", vm->def->name);
> @@ -391,6 +442,62 @@ error:
>      return -1;
>  }
>  
> +static int
> +libxlDomainSetVcpuAffinites(libxlDriverPrivatePtr driver, virDomainObjPtr vm)
> +{
> +    libxlDomainObjPrivatePtr priv = vm->privateData;
> +    virDomainDefPtr def = vm->def;
> +    libxl_cpumap map;
> +    uint8_t *cpumask = NULL;
> +    uint8_t *cpumap = NULL;
> +    virNodeInfo nodeinfo;
> +    size_t cpumaplen;
> +    unsigned int pos;
> +    int vcpu, i;
> +    int ret = -1;
> +
> +    if (libxlDoNodeGetInfo(driver, &nodeinfo) < 0)
> +        goto cleanup;
> +
> +    cpumaplen = VIR_CPU_MAPLEN(VIR_NODEINFO_MAXCPUS(nodeinfo));
> +
> +    for (vcpu = 0; vcpu < def->cputune.nvcpupin; ++vcpu) {
> +        if (vcpu != def->cputune.vcpupin[vcpu]->vcpuid)
> +            continue;
> +
> +        if (VIR_ALLOC_N(cpumap, cpumaplen) < 0) {
> +            virReportOOMError();
> +            goto cleanup;
> +        }
> +
> +        cpumask = (uint8_t*) def->cputune.vcpupin[vcpu]->cpumask;
> +
> +        for (i = 0; i < VIR_DOMAIN_CPUMASK_LEN; ++i) {
> +            if (cpumask[i]) {
> +                pos = i / 8;
> +                cpumap[pos] |= 1 << (i % 8);
> +            }
> +        }
> +
> +        map.size = cpumaplen;
> +        map.map = cpumap;
> +
> +        if (libxl_set_vcpuaffinity(&priv->ctx, def->id, vcpu, &map) != 0) {
> +            libxlError(VIR_ERR_INTERNAL_ERROR,
> +                       _("Failed to pin vcpu '%d' with libxenlight"), vcpu);
> +            goto cleanup;
> +        }
> +
> +        VIR_FREE(cpumap);
> +    }
> +
> +    ret = 0;
> +
> +cleanup:
> +    VIR_FREE(cpumap);
> +    return ret;
> +}
> +
>  /*
>   * Start a domain through libxenlight.
>   *
> @@ -440,6 +547,9 @@ libxlVmStart(libxlDriverPrivatePtr driver,
>      if (libxlCreateDomEvents(vm) < 0)
>          goto error;
>  
> +    if (libxlDomainSetVcpuAffinites(driver, vm) < 0)
> +        goto error;
> +
>      if (!start_paused) {
>          libxl_domain_unpause(&priv->ctx, domid);
>          vm->state = VIR_DOMAIN_RUNNING;
> @@ -756,7 +866,7 @@ libxlReload(void)
>                              &libxl_driver->domains,
>                              libxl_driver->configDir,
>                              libxl_driver->autostartDir,
> -                            0, NULL, libxl_driver);
> +                            1, NULL, libxl_driver);
>  
>      virHashForEach(libxl_driver->domains.objs, libxlAutostartDomain,
>                     libxl_driver);
> @@ -869,42 +979,7 @@ libxlGetMaxVcpus(virConnectPtr conn, const char *type ATTRIBUTE_UNUSED)
>  static int
>  libxlNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info)
>  {
> -    libxl_physinfo phy_info;
> -    const libxl_version_info* ver_info;
> -    libxlDriverPrivatePtr driver = conn->privateData;
> -    struct utsname utsname;
> -
> -    if (libxl_get_physinfo(&driver->ctx, &phy_info)) {
> -        libxlError(VIR_ERR_INTERNAL_ERROR,
> -                   _("libxl_get_physinfo_info failed"));
> -        return -1;
> -    }
> -
> -    if ((ver_info = libxl_get_version_info(&driver->ctx)) == NULL) {
> -        libxlError(VIR_ERR_INTERNAL_ERROR,
> -                   _("libxl_get_version_info failed"));
> -        return -1;
> -    }
> -
> -    uname(&utsname);
> -    if (virStrncpy(info->model,
> -                   utsname.machine,
> -                   strlen(utsname.machine),
> -                   sizeof(info->model)) == NULL) {
> -        libxlError(VIR_ERR_INTERNAL_ERROR,
> -                   _("machine type %s too big for destination"),
> -                   utsname.machine);
> -        return -1;
> -    }
> -
> -    info->memory = phy_info.total_pages * (ver_info->pagesize / 1024);
> -    info->cpus = phy_info.nr_cpus;
> -    info->nodes = phy_info.nr_nodes;
> -    info->cores = phy_info.cores_per_socket;
> -    info->threads = phy_info.threads_per_core;
> -    info->sockets = 1;
> -    info->mhz = phy_info.cpu_khz / 1000;
> -    return 0;
> +    return libxlDoNodeGetInfo(conn->privateData, info);
>  }
>  
>  static char *
> @@ -1712,6 +1787,16 @@ libxlDomainPinVcpu(virDomainPtr dom, unsigned int vcpu, unsigned char *cpumap,
>                     _("Failed to pin vcpu '%d' with libxenlight"), vcpu);
>          goto cleanup;
>      }
> +
> +    if (virDomainVcpupinAdd(vm->def, cpumap, maplen, vcpu) < 0) {
> +        libxlError(VIR_ERR_INTERNAL_ERROR,
> +                   "%s", _("failed to update or add vcpupin xml"));
> +        goto cleanup;
> +    }
> +
> +    if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
> +        goto cleanup;
> +
>      ret = 0;
>  
>  cleanup:
>   




More information about the libvir-list mailing list