[libvirt] [RFCv2 PATCH 5/5] conf: add memory bandwidth allocation capability of host

bing.niu at intel.com bing.niu at intel.com
Fri Jun 15 09:29:29 UTC 2018


From: Bing Niu <bing.niu at intel.com>

Add new XML section to report host's memory bandwidth allocation
capability. The format as below example:

 <host>
 .....
    <memory>
        <node id='0' cpus='0-19'>
            <control granularity='10' min ='10' maxAllocs='8'/>
        </node>
    </memory>
</host>

granularity   ---- granularity of memory bandwidth, unit percentage.
min           ---- minimum memory bandwidth allowed, unit percentage.
maxAllocs     ---- maximum memory bandwidth allocation group supported.

Signed-off-by: Bing Niu <bing.niu at intel.com>
---
 src/conf/capabilities.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/conf/capabilities.h |  11 +++++
 src/util/virresctrl.c   |  20 +++++++++
 src/util/virresctrl.h   |  15 +++++++
 4 files changed, 154 insertions(+)

diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c
index 7a810ef..3bba153 100644
--- a/src/conf/capabilities.c
+++ b/src/conf/capabilities.c
@@ -198,6 +198,16 @@ virCapabilitiesFreeNUMAInfo(virCapsPtr caps)
 }
 
 static void
+virCapsHostMemoryNodeFree(virCapsHostMemoryNodePtr ptr)
+{
+    if (!ptr)
+        return;
+
+    virBitmapFree(ptr->cpus);
+    VIR_FREE(ptr);
+}
+
+static void
 virCapabilitiesClearSecModel(virCapsHostSecModelPtr secmodel)
 {
     size_t i;
@@ -239,6 +249,11 @@ virCapsDispose(void *object)
         virCapsHostCacheBankFree(caps->host.caches[i]);
     VIR_FREE(caps->host.caches);
 
+    for (i = 0; i < caps->host.nnodes; i++)
+        virCapsHostMemoryNodeFree(caps->host.nodes[i]);
+    VIR_FREE(caps->host.nodes);
+
+
     VIR_FREE(caps->host.netprefix);
     VIR_FREE(caps->host.pagesSize);
     virCPUDefFree(caps->host.cpu);
@@ -957,6 +972,58 @@ virCapabilitiesFormatCaches(virBufferPtr buf,
     return 0;
 }
 
+static int
+virCapabilitiesFormatMemory(virBufferPtr buf,
+                            size_t nnodes,
+                            virCapsHostMemoryNodePtr *nodes)
+{
+    size_t i = 0;
+    virBuffer controlBuf = VIR_BUFFER_INITIALIZER;
+
+    if (!nnodes)
+        return 0;
+
+    virBufferAddLit(buf, "<memory>\n");
+    virBufferAdjustIndent(buf, 2);
+
+    for (i = 0; i < nnodes; i++) {
+        virCapsHostMemoryNodePtr node = nodes[i];
+        virResctrlInfoPerNodePtr control = &node->control;
+        char *cpus_str = virBitmapFormat(node->cpus);
+
+        if (!cpus_str)
+            return -1;
+
+        virBufferAsprintf(buf,
+                          "<node id='%u' cpus='%s'",
+                          node->id, cpus_str);
+        VIR_FREE(cpus_str);
+
+        virBufferSetChildIndent(&controlBuf, buf);
+        virBufferAsprintf(&controlBuf,
+                          "<control granularity='%u' min ='%u'"
+                          " maxAllocs='%u'/>\n",
+                          control->granularity, control->min,
+                          control->max_allocation);
+
+        if (virBufferCheckError(&controlBuf) < 0)
+            return -1;
+
+        if (virBufferUse(&controlBuf)) {
+            virBufferAddLit(buf, ">\n");
+            virBufferAddBuffer(buf, &controlBuf);
+            virBufferAddLit(buf, "</node>\n");
+        } else {
+            virBufferAddLit(buf, "/>\n");
+        }
+    }
+
+    virBufferAdjustIndent(buf, -2);
+    virBufferAddLit(buf, "</memory>\n");
+
+    return 0;
+}
+
 /**
  * virCapabilitiesFormatXML:
  * @caps: capabilities to format
@@ -1060,6 +1127,10 @@ virCapabilitiesFormatXML(virCapsPtr caps)
                                     caps->host.caches) < 0)
         goto error;
 
+    if (virCapabilitiesFormatMemory(&buf, caps->host.nnodes,
+                                    caps->host.nodes) < 0)
+        goto error;
+
     for (i = 0; i < caps->host.nsecModels; i++) {
         virBufferAddLit(&buf, "<secmodel>\n");
         virBufferAdjustIndent(&buf, 2);
@@ -1602,6 +1673,40 @@ virCapabilitiesInitResctrl(virCapsPtr caps)
 }
 
 
+static int
+virCapabilitiesInitResctrlMemory(virCapsPtr caps)
+{
+    virCapsHostMemoryNodePtr node = NULL;
+    size_t i = 0;
+    int ret = -1;
+
+    for (i = 0; i < caps->host.ncaches; i++) {
+        virCapsHostCacheBankPtr bank = caps->host.caches[i];
+        if (VIR_ALLOC(node) < 0)
+            goto cleanup;
+
+        if (virResctrlInfoGetMemory(caps->host.resctrl, bank->level, &node->control) > 0) {
+            node->id = bank->id;
+            if (!(node->cpus = virBitmapNewCopy(bank->cpus)))
+                goto cleanup;
+
+            if (VIR_APPEND_ELEMENT(caps->host.nodes,
+                                   caps->host.nnodes,
+                                   node) < 0) {
+                goto cleanup;
+            }
+        }
+        virCapsHostMemoryNodeFree(node);
+        node = NULL;
+    }
+
+    ret = 0;
+ cleanup:
+    virCapsHostMemoryNodeFree(node);
+    return ret;
+}
+
+
 int
 virCapabilitiesInitCaches(virCapsPtr caps)
 {
@@ -1731,6 +1836,9 @@ virCapabilitiesInitCaches(virCapsPtr caps)
     qsort(caps->host.caches, caps->host.ncaches,
           sizeof(*caps->host.caches), virCapsHostCacheBankSorter);
 
+    if (virCapabilitiesInitResctrlMemory(caps) < 0)
+        goto cleanup;
+
     ret = 0;
  cleanup:
     VIR_FREE(type);
diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h
index fe1b9ea..73e165e 100644
--- a/src/conf/capabilities.h
+++ b/src/conf/capabilities.h
@@ -151,6 +151,14 @@ struct _virCapsHostCacheBank {
     virResctrlInfoPerCachePtr *controls;
 };
 
+typedef struct _virCapsHostMemoryNode virCapsHostMemoryNode;
+typedef virCapsHostMemoryNode *virCapsHostMemoryNodePtr;
+struct _virCapsHostMemoryNode {
+    unsigned int id;
+    virBitmapPtr cpus;  /* All CPUs that belong to this node*/
+    virResctrlInfoPerNode control;
+};
+
 typedef struct _virCapsHost virCapsHost;
 typedef virCapsHost *virCapsHostPtr;
 struct _virCapsHost {
@@ -175,6 +183,9 @@ struct _virCapsHost {
     size_t ncaches;
     virCapsHostCacheBankPtr *caches;
 
+    size_t nnodes;
+    virCapsHostMemoryNodePtr *nodes;
+
     size_t nsecModels;
     virCapsHostSecModelPtr secModels;
 
diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c
index de736b0..17f0a58 100644
--- a/src/util/virresctrl.c
+++ b/src/util/virresctrl.c
@@ -611,6 +611,26 @@ virResctrlInfoIsEmpty(virResctrlInfoPtr resctrl)
 
 
 int
+virResctrlInfoGetMemory(virResctrlInfoPtr resctrl,
+                       unsigned int level,
+                       virResctrlInfoPerNodePtr control)
+{
+    virResctrlInfoMBPtr mb_info = resctrl->mb_info;
+
+    if (!mb_info)
+        return 0;
+
+    if (mb_info->last_level_cache != level)
+        return 0;
+
+    control->granularity = mb_info->bandwidth_granularity;
+    control->min = mb_info->min_bandwidth;
+    control->max_allocation = mb_info->max_allocation;
+    return 1;
+}
+
+
+int
 virResctrlInfoGetCache(virResctrlInfoPtr resctrl,
                        unsigned int level,
                        unsigned long long size,
diff --git a/src/util/virresctrl.h b/src/util/virresctrl.h
index 5e78334..01fcade 100644
--- a/src/util/virresctrl.h
+++ b/src/util/virresctrl.h
@@ -50,6 +50,17 @@ struct _virResctrlInfoPerCache {
     unsigned int max_allocation;
 };
 
+typedef struct _virResctrlInfoPerNode virResctrlInfoPerNode;
+typedef virResctrlInfoPerNode *virResctrlInfoPerNodePtr;
+struct _virResctrlInfoPerNode {
+    /* Smallest possible increase of the allocation bandwidth in percentage */
+    unsigned int granularity;
+    /* Minimal allocatable bandwidth in percentage */
+    unsigned int min;
+    /* Maximum number of simultaneous allocations */
+    unsigned int max_allocation;
+};
+
 typedef struct _virResctrlInfo virResctrlInfo;
 typedef virResctrlInfo *virResctrlInfoPtr;
 
@@ -63,6 +74,10 @@ virResctrlInfoGetCache(virResctrlInfoPtr resctrl,
                        size_t *ncontrols,
                        virResctrlInfoPerCachePtr **controls);
 
+int
+virResctrlInfoGetMemory(virResctrlInfoPtr resctrl,
+                        unsigned int level,
+                        virResctrlInfoPerNodePtr control);
 /* Alloc-related things */
 typedef struct _virResctrlAlloc virResctrlAlloc;
 typedef virResctrlAlloc *virResctrlAllocPtr;
-- 
2.7.4




More information about the libvir-list mailing list