]> xenbits.xensource.com Git - libvirt.git/commitdiff
caps: Add helpers to convert NUMA nodes to corresponding CPUs
authorPeter Krempa <pkrempa@redhat.com>
Thu, 18 Jul 2013 09:21:48 +0000 (11:21 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Thu, 18 Jul 2013 12:41:01 +0000 (14:41 +0200)
These helpers use the remembered host capabilities to retrieve the cpu
map rather than query the host again. The intended usage for this
helpers is to fix automatic NUMA placement with strict memory alloc. The
code doing the prepare needs to pin the emulator process only to cpus
belonging to a subset of NUMA nodes of the host.

po/POTFILES.in
src/conf/capabilities.c
src/conf/capabilities.h
src/libvirt_private.syms

index 2e4ebc8011a054f14b654799100fdbd4371c040a..1fd84af58afd8171e06e2d352fd3a1656437f20d 100644 (file)
@@ -8,6 +8,7 @@ gnulib/lib/gai_strerror.c
 gnulib/lib/regcomp.c
 src/access/viraccessdriverpolkit.c
 src/access/viraccessmanager.c
+src/conf/capabilities.c
 src/conf/cpu_conf.c
 src/conf/device_conf.c
 src/conf/domain_conf.c
index bb5fe4ec60f915cb9668cbef82dde8f4479d8916..1acc9366f7b604f84e4caacc5144842e04956129 100644 (file)
@@ -916,3 +916,67 @@ virCapabilitiesFormatXML(virCapsPtr caps)
 
     return virBufferContentAndReset(&xml);
 }
+
+/* get the maximum ID of cpus in the host */
+static unsigned int
+virCapabilitiesGetHostMaxcpu(virCapsPtr caps)
+{
+    unsigned int maxcpu = 0;
+    size_t node;
+    size_t cpu;
+
+    for (node = 0; node < caps->host.nnumaCell; node++) {
+        virCapsHostNUMACellPtr cell = caps->host.numaCell[node];
+
+        for (cpu = 0; cpu < cell->ncpus; cpu++) {
+            if (cell->cpus[cpu].id > maxcpu)
+                maxcpu = cell->cpus[cpu].id;
+        }
+    }
+
+    return maxcpu;
+}
+
+/* set cpus of a numa node in the bitmask */
+static int
+virCapabilitiesGetCpusForNode(virCapsPtr caps,
+                              size_t node,
+                              virBitmapPtr cpumask)
+{
+    virCapsHostNUMACellPtr cell = caps->host.numaCell[node];
+    size_t cpu;
+
+    for (cpu = 0; cpu < cell->ncpus; cpu++) {
+        if (virBitmapSetBit(cpumask, cell->cpus[cpu].id) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Cpu '%u' in node '%zu' is out of range "
+                             "of the provided bitmap"),
+                           cell->cpus[cpu].id, node);
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+virBitmapPtr
+virCapabilitiesGetCpusForNodemask(virCapsPtr caps,
+                                  virBitmapPtr nodemask)
+{
+    virBitmapPtr ret = NULL;
+    unsigned int maxcpu = virCapabilitiesGetHostMaxcpu(caps);
+    ssize_t node = -1;
+
+    if (!(ret = virBitmapNew(maxcpu + 1)))
+        return NULL;
+
+
+    while ((node = virBitmapNextSetBit(nodemask, node)) >= 0) {
+        if (virCapabilitiesGetCpusForNode(caps, node, ret) < 0) {
+            virBitmapFree(ret);
+            return NULL;
+        }
+    }
+
+    return ret;
+}
index 6c7efdefdb54ab529593b881b3180b4a42f96c34..88ec4547f7ff9ebbf2c369cd49d3c79f47ef6e11 100644 (file)
@@ -257,5 +257,7 @@ virCapabilitiesDefaultGuestEmulator(virCapsPtr caps,
 extern char *
 virCapabilitiesFormatXML(virCapsPtr caps);
 
+virBitmapPtr virCapabilitiesGetCpusForNodemask(virCapsPtr caps,
+                                               virBitmapPtr nodemask);
 
 #endif /* __VIR_CAPABILITIES_H */
index 7a968fb0ec5f2745c111a61719782577921cf612..ba9db26fd37d4070c43ca4c44f11a19586ae3f50 100644 (file)
@@ -57,6 +57,7 @@ virCapabilitiesDefaultGuestMachine;
 virCapabilitiesFormatXML;
 virCapabilitiesFreeMachines;
 virCapabilitiesFreeNUMAInfo;
+virCapabilitiesGetCpusForNodemask;
 virCapabilitiesNew;
 virCapabilitiesSetHostCPU;