mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 13:45:38 +00:00
conf: Add memory bandwidth allocation capability of host
Add new XML section to report host's memory bandwidth allocation capability. The format as below example: <host> ..... <memory_bandwidth> <node id='0' cpus='0-19'> <control granularity='10' min ='10' maxAllocs='8'/> </node> </memory_bandwidth> </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@intel.com> Reviewed-by: John Ferlan <jferlan@redhat.com>
This commit is contained in:
parent
8d6f508e64
commit
7995fecc25
@ -51,6 +51,9 @@
|
|||||||
<optional>
|
<optional>
|
||||||
<ref name='cache'/>
|
<ref name='cache'/>
|
||||||
</optional>
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<ref name='memory_bandwidth'/>
|
||||||
|
</optional>
|
||||||
<zeroOrMore>
|
<zeroOrMore>
|
||||||
<ref name='secmodel'/>
|
<ref name='secmodel'/>
|
||||||
</zeroOrMore>
|
</zeroOrMore>
|
||||||
@ -326,6 +329,36 @@
|
|||||||
</attribute>
|
</attribute>
|
||||||
</define>
|
</define>
|
||||||
|
|
||||||
|
<define name='memory_bandwidth'>
|
||||||
|
<element name='memory_bandwidth'>
|
||||||
|
<oneOrMore>
|
||||||
|
<element name='node'>
|
||||||
|
<attribute name='id'>
|
||||||
|
<ref name='unsignedInt'/>
|
||||||
|
</attribute>
|
||||||
|
<attribute name='cpus'>
|
||||||
|
<ref name='cpuset'/>
|
||||||
|
</attribute>
|
||||||
|
<zeroOrMore>
|
||||||
|
<element name='control'>
|
||||||
|
<attribute name='granularity'>
|
||||||
|
<ref name='unsignedInt'/>
|
||||||
|
</attribute>
|
||||||
|
<optional>
|
||||||
|
<attribute name='min'>
|
||||||
|
<ref name='unsignedInt'/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
|
<attribute name='maxAllocs'>
|
||||||
|
<ref name='unsignedInt'/>
|
||||||
|
</attribute>
|
||||||
|
</element>
|
||||||
|
</zeroOrMore>
|
||||||
|
</element>
|
||||||
|
</oneOrMore>
|
||||||
|
</element>
|
||||||
|
</define>
|
||||||
|
|
||||||
<define name='guestcaps'>
|
<define name='guestcaps'>
|
||||||
<element name='guest'>
|
<element name='guest'>
|
||||||
<ref name='ostype'/>
|
<ref name='ostype'/>
|
||||||
|
@ -197,6 +197,16 @@ virCapabilitiesFreeNUMAInfo(virCapsPtr caps)
|
|||||||
caps->host.nnumaCell = 0;
|
caps->host.nnumaCell = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
virCapsHostMemBWNodeFree(virCapsHostMemBWNodePtr ptr)
|
||||||
|
{
|
||||||
|
if (!ptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
virBitmapFree(ptr->cpus);
|
||||||
|
VIR_FREE(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
virCapabilitiesClearSecModel(virCapsHostSecModelPtr secmodel)
|
virCapabilitiesClearSecModel(virCapsHostSecModelPtr secmodel)
|
||||||
{
|
{
|
||||||
@ -239,6 +249,10 @@ virCapsDispose(void *object)
|
|||||||
virCapsHostCacheBankFree(caps->host.caches[i]);
|
virCapsHostCacheBankFree(caps->host.caches[i]);
|
||||||
VIR_FREE(caps->host.caches);
|
VIR_FREE(caps->host.caches);
|
||||||
|
|
||||||
|
for (i = 0; i < caps->host.nnodes; i++)
|
||||||
|
virCapsHostMemBWNodeFree(caps->host.nodes[i]);
|
||||||
|
VIR_FREE(caps->host.nodes);
|
||||||
|
|
||||||
VIR_FREE(caps->host.netprefix);
|
VIR_FREE(caps->host.netprefix);
|
||||||
VIR_FREE(caps->host.pagesSize);
|
VIR_FREE(caps->host.pagesSize);
|
||||||
virCPUDefFree(caps->host.cpu);
|
virCPUDefFree(caps->host.cpu);
|
||||||
@ -946,6 +960,58 @@ virCapabilitiesFormatCaches(virBufferPtr buf,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virCapabilitiesFormatMemoryBandwidth(virBufferPtr buf,
|
||||||
|
size_t nnodes,
|
||||||
|
virCapsHostMemBWNodePtr *nodes)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
virBuffer controlBuf = VIR_BUFFER_INITIALIZER;
|
||||||
|
|
||||||
|
if (!nnodes)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
virBufferAddLit(buf, "<memory_bandwidth>\n");
|
||||||
|
virBufferAdjustIndent(buf, 2);
|
||||||
|
|
||||||
|
for (i = 0; i < nnodes; i++) {
|
||||||
|
virCapsHostMemBWNodePtr node = nodes[i];
|
||||||
|
virResctrlInfoMemBWPerNodePtr 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_bandwidth>\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virCapabilitiesFormatXML:
|
* virCapabilitiesFormatXML:
|
||||||
* @caps: capabilities to format
|
* @caps: capabilities to format
|
||||||
@ -1049,6 +1115,10 @@ virCapabilitiesFormatXML(virCapsPtr caps)
|
|||||||
caps->host.caches) < 0)
|
caps->host.caches) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
if (virCapabilitiesFormatMemoryBandwidth(&buf, caps->host.nnodes,
|
||||||
|
caps->host.nodes) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
for (i = 0; i < caps->host.nsecModels; i++) {
|
for (i = 0; i < caps->host.nsecModels; i++) {
|
||||||
virBufferAddLit(&buf, "<secmodel>\n");
|
virBufferAddLit(&buf, "<secmodel>\n");
|
||||||
virBufferAdjustIndent(&buf, 2);
|
virBufferAdjustIndent(&buf, 2);
|
||||||
@ -1591,6 +1661,40 @@ virCapabilitiesInitResctrl(virCapsPtr caps)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virCapabilitiesInitResctrlMemory(virCapsPtr caps)
|
||||||
|
{
|
||||||
|
virCapsHostMemBWNodePtr 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 (virResctrlInfoGetMemoryBandwidth(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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virCapsHostMemBWNodeFree(node);
|
||||||
|
node = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
cleanup:
|
||||||
|
virCapsHostMemBWNodeFree(node);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
virCapabilitiesInitCaches(virCapsPtr caps)
|
virCapabilitiesInitCaches(virCapsPtr caps)
|
||||||
{
|
{
|
||||||
@ -1720,6 +1824,9 @@ virCapabilitiesInitCaches(virCapsPtr caps)
|
|||||||
qsort(caps->host.caches, caps->host.ncaches,
|
qsort(caps->host.caches, caps->host.ncaches,
|
||||||
sizeof(*caps->host.caches), virCapsHostCacheBankSorter);
|
sizeof(*caps->host.caches), virCapsHostCacheBankSorter);
|
||||||
|
|
||||||
|
if (virCapabilitiesInitResctrlMemory(caps) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
cleanup:
|
cleanup:
|
||||||
VIR_FREE(type);
|
VIR_FREE(type);
|
||||||
|
@ -151,6 +151,14 @@ struct _virCapsHostCacheBank {
|
|||||||
virResctrlInfoPerCachePtr *controls;
|
virResctrlInfoPerCachePtr *controls;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct _virCapsHostMemBWNode virCapsHostMemBWNode;
|
||||||
|
typedef virCapsHostMemBWNode *virCapsHostMemBWNodePtr;
|
||||||
|
struct _virCapsHostMemBWNode {
|
||||||
|
unsigned int id;
|
||||||
|
virBitmapPtr cpus; /* All CPUs that belong to this node*/
|
||||||
|
virResctrlInfoMemBWPerNode control;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct _virCapsHost virCapsHost;
|
typedef struct _virCapsHost virCapsHost;
|
||||||
typedef virCapsHost *virCapsHostPtr;
|
typedef virCapsHost *virCapsHostPtr;
|
||||||
struct _virCapsHost {
|
struct _virCapsHost {
|
||||||
@ -175,6 +183,9 @@ struct _virCapsHost {
|
|||||||
size_t ncaches;
|
size_t ncaches;
|
||||||
virCapsHostCacheBankPtr *caches;
|
virCapsHostCacheBankPtr *caches;
|
||||||
|
|
||||||
|
size_t nnodes;
|
||||||
|
virCapsHostMemBWNodePtr *nodes;
|
||||||
|
|
||||||
size_t nsecModels;
|
size_t nsecModels;
|
||||||
virCapsHostSecModelPtr secModels;
|
virCapsHostSecModelPtr secModels;
|
||||||
|
|
||||||
|
@ -629,6 +629,26 @@ virResctrlInfoIsEmpty(virResctrlInfoPtr resctrl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
virResctrlInfoGetMemoryBandwidth(virResctrlInfoPtr resctrl,
|
||||||
|
unsigned int level,
|
||||||
|
virResctrlInfoMemBWPerNodePtr control)
|
||||||
|
{
|
||||||
|
virResctrlInfoMemBWPtr membw_info = resctrl->membw_info;
|
||||||
|
|
||||||
|
if (!membw_info)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (membw_info->last_level_cache != level)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
control->granularity = membw_info->bandwidth_granularity;
|
||||||
|
control->min = membw_info->min_bandwidth;
|
||||||
|
control->max_allocation = membw_info->max_allocation;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
virResctrlInfoGetCache(virResctrlInfoPtr resctrl,
|
virResctrlInfoGetCache(virResctrlInfoPtr resctrl,
|
||||||
unsigned int level,
|
unsigned int level,
|
||||||
|
@ -50,6 +50,17 @@ struct _virResctrlInfoPerCache {
|
|||||||
unsigned int max_allocation;
|
unsigned int max_allocation;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct _virResctrlInfoMemBWPerNode virResctrlInfoMemBWPerNode;
|
||||||
|
typedef virResctrlInfoMemBWPerNode *virResctrlInfoMemBWPerNodePtr;
|
||||||
|
struct _virResctrlInfoMemBWPerNode {
|
||||||
|
/* 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 struct _virResctrlInfo virResctrlInfo;
|
||||||
typedef virResctrlInfo *virResctrlInfoPtr;
|
typedef virResctrlInfo *virResctrlInfoPtr;
|
||||||
|
|
||||||
@ -63,6 +74,10 @@ virResctrlInfoGetCache(virResctrlInfoPtr resctrl,
|
|||||||
size_t *ncontrols,
|
size_t *ncontrols,
|
||||||
virResctrlInfoPerCachePtr **controls);
|
virResctrlInfoPerCachePtr **controls);
|
||||||
|
|
||||||
|
int
|
||||||
|
virResctrlInfoGetMemoryBandwidth(virResctrlInfoPtr resctrl,
|
||||||
|
unsigned int level,
|
||||||
|
virResctrlInfoMemBWPerNodePtr control);
|
||||||
/* Alloc-related things */
|
/* Alloc-related things */
|
||||||
typedef struct _virResctrlAlloc virResctrlAlloc;
|
typedef struct _virResctrlAlloc virResctrlAlloc;
|
||||||
typedef virResctrlAlloc *virResctrlAllocPtr;
|
typedef virResctrlAlloc *virResctrlAllocPtr;
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
10
|
@ -0,0 +1 @@
|
|||||||
|
10
|
@ -0,0 +1 @@
|
|||||||
|
4
|
@ -49,6 +49,14 @@
|
|||||||
<control granularity='768' min='1536' unit='KiB' type='both' maxAllocs='4'/>
|
<control granularity='768' min='1536' unit='KiB' type='both' maxAllocs='4'/>
|
||||||
</bank>
|
</bank>
|
||||||
</cache>
|
</cache>
|
||||||
|
<memory_bandwidth>
|
||||||
|
<node id='0' cpus='0-5'>
|
||||||
|
<control granularity='10' min ='10' maxAllocs='4'/>
|
||||||
|
</node>
|
||||||
|
<node id='1' cpus='6-11'>
|
||||||
|
<control granularity='10' min ='10' maxAllocs='4'/>
|
||||||
|
</node>
|
||||||
|
</memory_bandwidth>
|
||||||
</host>
|
</host>
|
||||||
|
|
||||||
</capabilities>
|
</capabilities>
|
||||||
|
@ -1 +1,2 @@
|
|||||||
L3:0=000ff;1=000f0
|
L3:0=000ff;1=000f0
|
||||||
|
MB:0=100;1=100
|
||||||
|
Loading…
Reference in New Issue
Block a user