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

Markus Groß gross at univention.de
Mon Apr 18 09:16:33 UTC 2011


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(-)

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:
-- 
1.7.1




More information about the libvir-list mailing list