]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
capabilities: add NUMA memory information
authorDusty Mabe <dustymabe@gmail.com>
Thu, 7 Mar 2013 16:03:36 +0000 (11:03 -0500)
committerEric Blake <eblake@redhat.com>
Fri, 8 Mar 2013 18:51:00 +0000 (11:51 -0700)
'virsh capabilities' will now include a new <memory> element
per <cell> of the topology, as in:

    <topology>
      <cells num='2'>
        <cell id='0'>
          <memory unit='KiB'>12572412</memory>
          <cpus num='12'>
          ...
        </cell>

Signed-off-by: Eric Blake <eblake@redhat.com>
docs/schemas/capability.rng
src/conf/capabilities.c
src/conf/capabilities.h
src/nodeinfo.c
src/test/test_driver.c
src/xen/xend_internal.c
tests/capabilityschemadata/caps-test3.xml [new file with mode: 0644]

index 8f3fbd9ae2103f245a79bc3aefd82dace3a27ba1..106ca73126e593ce9d6dc67d09611a88f6e05738 100644 (file)
         <ref name='unsignedInt'/>
       </attribute>
 
+      <optional>
+        <ref name='memory'/>
+      </optional>
+
       <optional>
         <element name='cpus'>
           <attribute name='num'>
     </element>
   </define>
 
+  <define name='memory'>
+    <element name='memory'>
+      <ref name='scaledInteger'/>
+    </element>
+  </define>
+
   <define name='cpu'>
     <element name='cpu'>
       <attribute name='id'>
index a0e597b232d42277aa10b0d791ae06768beb96ca..d53d5a3b440dca0d20045d9f72353f541c822c1a 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * capabilities.c: hypervisor capabilities
  *
- * Copyright (C) 2006-2008, 2010-2011 Red Hat, Inc.
+ * Copyright (C) 2006-2008, 2010-2011, 2013 Red Hat, Inc.
  * Copyright (C) 2006-2008 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
@@ -273,6 +273,7 @@ int
 virCapabilitiesAddHostNUMACell(virCapsPtr caps,
                                int num,
                                int ncpus,
+                               unsigned long long mem,
                                virCapsHostNUMACellCPUPtr cpus)
 {
     virCapsHostNUMACellPtr cell;
@@ -286,6 +287,7 @@ virCapabilitiesAddHostNUMACell(virCapsPtr caps,
 
     cell->ncpus = ncpus;
     cell->num = num;
+    cell->mem = mem;
     cell->cpus = cpus;
 
     caps->host.numaCell[caps->host.nnumaCell++] = cell;
@@ -712,6 +714,13 @@ virCapabilitiesFormatNUMATopology(virBufferPtr xml,
     virBufferAsprintf(xml, "      <cells num='%zu'>\n", ncells);
     for (i = 0; i < ncells; i++) {
         virBufferAsprintf(xml, "        <cell id='%d'>\n", cells[i]->num);
+
+        /* Print out the numacell memory total if it is available */
+        if (cells[i]->mem)
+            virBufferAsprintf(xml,
+                              "          <memory unit='KiB'>%llu</memory>\n",
+                              cells[i]->mem);
+
         virBufferAsprintf(xml, "          <cpus num='%d'>\n", cells[i]->ncpus);
         for (j = 0; j < cells[i]->ncpus; j++) {
             virBufferAsprintf(xml, "            <cpu id='%d'",
index cc01765acac229e37327e4f7bf83fd71c68e5e8b..6c67fb32b02b2951284f1f1d175af6a29e32bf60 100644 (file)
@@ -99,6 +99,7 @@ typedef virCapsHostNUMACell *virCapsHostNUMACellPtr;
 struct _virCapsHostNUMACell {
     int num;
     int ncpus;
+    unsigned long long mem; /* in kibibytes */
     virCapsHostNUMACellCPUPtr cpus;
 };
 
@@ -210,6 +211,7 @@ extern int
 virCapabilitiesAddHostNUMACell(virCapsPtr caps,
                                int num,
                                int ncpus,
+                               unsigned long long mem,
                                virCapsHostNUMACellCPUPtr cpus);
 
 
index 162232215d2fcfebd3738d700de74e07e76a7d68..b80e389a7129c43814b5326ff6c97c36b6086fce 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * nodeinfo.c: Helper routines for OS specific node information
  *
- * Copyright (C) 2006-2008, 2010-2012 Red Hat, Inc.
+ * Copyright (C) 2006-2008, 2010-2013 Red Hat, Inc.
  * Copyright (C) 2006 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
@@ -102,6 +102,7 @@ static int linuxNodeGetMemoryStats(FILE *meminfo,
                                    int cellNum,
                                    virNodeMemoryStatsPtr params,
                                    int *nparams);
+static unsigned long long nodeGetCellMemory(int cell);
 
 /* Return the positive decimal contents of the given
  * DIR/cpu%u/FILE, or -1 on error.  If DEFAULT_VALUE is non-negative
@@ -1531,6 +1532,7 @@ nodeCapsInitNUMA(virCapsPtr caps)
     int n;
     unsigned long *mask = NULL;
     unsigned long *allonesmask = NULL;
+    unsigned long long memory;
     virCapsHostNUMACellCPUPtr cpus = NULL;
     int ret = -1;
     int max_n_cpus = NUMA_MAX_N_CPUS;
@@ -1562,6 +1564,9 @@ nodeCapsInitNUMA(virCapsPtr caps)
             continue;
         }
 
+        /* Detect the amount of memory in the numa cell */
+        memory = nodeGetCellMemory(n);
+
         for (ncpus = 0, i = 0 ; i < max_n_cpus ; i++)
             if (MASK_CPU_ISSET(mask, i))
                 ncpus++;
@@ -1578,7 +1583,7 @@ nodeCapsInitNUMA(virCapsPtr caps)
             }
         }
 
-        if (virCapabilitiesAddHostNUMACell(caps, n, ncpus, cpus) < 0)
+        if (virCapabilitiesAddHostNUMACell(caps, n, ncpus, memory, cpus) < 0)
             goto cleanup;
     }
 
@@ -1665,6 +1670,48 @@ cleanup:
     return freeMem;
 }
 
+/**
+ * nodeGetCellMemory
+ * @cell: The number of the numa cell to get memory info for.
+ *
+ * Will call the numa_node_size64() function from libnuma to get
+ * the amount of total memory in bytes. It is then converted to
+ * KiB and returned.
+ *
+ * Returns 0 if unavailable, amount of memory in KiB on success.
+ */
+static unsigned long long nodeGetCellMemory(int cell)
+{
+    long long mem;
+    unsigned long long memKiB = 0;
+    int maxCell;
+
+    /* Make sure the provided cell number is valid. */
+    maxCell = numa_max_node();
+    if (cell > maxCell) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("cell %d out of range (0-%d)"),
+                       cell, maxCell);
+        goto cleanup;
+    }
+
+    /* Get the amount of memory(bytes) in the node */
+    mem = numa_node_size64(cell, NULL);
+    if (mem < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Failed to query NUMA total memory for node: %d"),
+                       cell);
+        goto cleanup;
+    }
+
+    /* Convert the memory from bytes to KiB */
+    memKiB = mem >> 10;
+
+cleanup:
+    return memKiB;
+}
+
+
 #else
 int nodeCapsInitNUMA(virCapsPtr caps ATTRIBUTE_UNUSED) {
     return 0;
@@ -1686,4 +1733,11 @@ unsigned long long nodeGetFreeMemory(virConnectPtr conn ATTRIBUTE_UNUSED)
                    _("NUMA memory information not available on this platform"));
     return 0;
 }
+
+static unsigned long long nodeGetCellMemory(int cell)
+{
+    virReportError(VIR_ERR_NO_SUPPORT, "%s",
+                   _("NUMA memory information not available on this platform"));
+    return 0;
+}
 #endif
index 30ce8e7e303ab8e63465b8954e4b140381de2627..0037a6fbffe40470fabef01ed0dc7d85369ff6d9 100644 (file)
@@ -184,7 +184,7 @@ testBuildCapabilities(virConnectPtr conn) {
 
 
         if (virCapabilitiesAddHostNUMACell(caps, i, privconn->cells[i].numCpus,
-                                           cpu_cells) < 0)
+                                           0, cpu_cells) < 0)
             goto no_memory;
     }
 
index 27b87fc60c5a73b089cdd7caf4ecb9ee79dc4d0a..4995d633f1335adb47cd544bdd855de7417ccc0f 100644 (file)
@@ -1141,7 +1141,7 @@ sexpr_to_xend_topology(const struct sexpr *root, virCapsPtr caps)
         }
         virBitmapFree(cpuset);
 
-        if (virCapabilitiesAddHostNUMACell(caps, cell, nb_cpus, cpuInfo) < 0)
+        if (virCapabilitiesAddHostNUMACell(caps, cell, nb_cpus, 0, cpuInfo) < 0)
             goto memory_error;
         cpuInfo = NULL;
     }
diff --git a/tests/capabilityschemadata/caps-test3.xml b/tests/capabilityschemadata/caps-test3.xml
new file mode 100644 (file)
index 0000000..e6c56c5
--- /dev/null
@@ -0,0 +1,88 @@
+<capabilities>
+
+  <host>
+    <uuid>35383339-3134-5553-4531-30314e394a50</uuid>
+    <cpu>
+      <arch>x86_64</arch>
+      <model>Westmere</model>
+      <vendor>Intel</vendor>
+      <topology sockets='1' cores='6' threads='2'/>
+      <feature name='rdtscp'/>
+      <feature name='pdpe1gb'/>
+      <feature name='dca'/>
+      <feature name='pdcm'/>
+      <feature name='xtpr'/>
+      <feature name='tm2'/>
+      <feature name='est'/>
+      <feature name='smx'/>
+      <feature name='vmx'/>
+      <feature name='ds_cpl'/>
+      <feature name='monitor'/>
+      <feature name='dtes64'/>
+      <feature name='pclmuldq'/>
+      <feature name='pbe'/>
+      <feature name='tm'/>
+      <feature name='ht'/>
+      <feature name='ss'/>
+      <feature name='acpi'/>
+      <feature name='ds'/>
+      <feature name='vme'/>
+    </cpu>
+    <power_management>
+      <suspend_disk/>
+    </power_management>
+    <migration_features>
+      <live/>
+      <uri_transports>
+        <uri_transport>tcp</uri_transport>
+      </uri_transports>
+    </migration_features>
+    <topology>
+      <cells num='2'>
+        <cell id='0'>
+          <memory unit='KiB'>12572412</memory>
+          <cpus num='12'>
+            <cpu id='0'/>
+            <cpu id='2'/>
+            <cpu id='4'/>
+            <cpu id='6'/>
+            <cpu id='8'/>
+            <cpu id='10'/>
+            <cpu id='12'/>
+            <cpu id='14'/>
+            <cpu id='16'/>
+            <cpu id='18'/>
+            <cpu id='20'/>
+            <cpu id='22'/>
+          </cpus>
+        </cell>
+        <cell id='1'>
+          <memory unit='KiB'>12582908</memory>
+          <cpus num='12'>
+            <cpu id='1'/>
+            <cpu id='3'/>
+            <cpu id='5'/>
+            <cpu id='7'/>
+            <cpu id='9'/>
+            <cpu id='11'/>
+            <cpu id='13'/>
+            <cpu id='15'/>
+            <cpu id='17'/>
+            <cpu id='19'/>
+            <cpu id='21'/>
+            <cpu id='23'/>
+          </cpus>
+        </cell>
+      </cells>
+    </topology>
+    <secmodel>
+      <model>none</model>
+      <doi>0</doi>
+    </secmodel>
+    <secmodel>
+      <model>dac</model>
+      <doi>0</doi>
+    </secmodel>
+  </host>
+
+</capabilities>