提交 0ab409cc 编写于 作者: E Eli Qiao 提交者: Martin Kletzander

Expose resource control capabilities for caches

Add cache resource control into capabilities for CAT without CDP:

  <cache>
    <bank id='0' level='3' type='unified' size='15360' unit='KiB' cpus='0-5'>
      <control min='768' unit='KiB' scope='both' max_allocation='4'/>
    </bank>
  </cache>

and with CDP:

  <cache>
    <bank id='0' level='3' type='unified' size='15360' unit='KiB' cpus='0-5'>
      <control min='768' unit='KiB' scope='code' max_allocation='4'/>
      <control min='768' unit='KiB' scope='data' max_allocation='4'/>
    </bank>
  </cache>

Also add new test cases for vircaps2xmltest.
Signed-off-by: NEli Qiao <liyong.qiao@intel.com>
上级 7b4e9b2c
......@@ -261,13 +261,7 @@
<attribute name='level'>
<ref name='unsignedInt'/>
</attribute>
<attribute name='type'>
<choice>
<value>both</value>
<value>code</value>
<value>data</value>
</choice>
</attribute>
<ref name='cacheType'/>
<attribute name='size'>
<ref name='unsignedInt'/>
</attribute>
......@@ -277,11 +271,35 @@
<attribute name='cpus'>
<ref name='cpuset'/>
</attribute>
<zeroOrMore>
<element name='control'>
<attribute name='min'>
<ref name='unsignedInt'/>
</attribute>
<attribute name='unit'>
<ref name='unit'/>
</attribute>
<ref name='cacheType'/>
<attribute name='maxAllocs'>
<ref name='unsignedInt'/>
</attribute>
</element>
</zeroOrMore>
</element>
</oneOrMore>
</element>
</define>
<define name='cacheType'>
<attribute name='type'>
<choice>
<value>both</value>
<value>code</value>
<value>data</value>
</choice>
</attribute>
</define>
<define name='guestcaps'>
<element name='guest'>
<ref name='ostype'/>
......
......@@ -51,6 +51,7 @@
#define VIR_FROM_THIS VIR_FROM_CAPABILITIES
#define SYSFS_SYSTEM_PATH "/sys/devices/system"
#define SYSFS_RESCTRL_PATH "/sys/fs/resctrl"
VIR_LOG_INIT("conf.capabilities")
......@@ -872,6 +873,9 @@ virCapabilitiesFormatCaches(virBufferPtr buf,
virCapsHostCacheBankPtr *caches)
{
size_t i = 0;
size_t j = 0;
int indent = virBufferGetIndent(buf, false);
virBuffer controlBuf = VIR_BUFFER_INITIALIZER;
if (!ncaches)
return 0;
......@@ -893,13 +897,33 @@ virCapabilitiesFormatCaches(virBufferPtr buf,
*/
virBufferAsprintf(buf,
"<bank id='%u' level='%u' type='%s' "
"size='%llu' unit='%s' cpus='%s'/>\n",
"size='%llu' unit='%s' cpus='%s'",
bank->id, bank->level,
virCacheTypeToString(bank->type),
bank->size >> (kilos * 10),
kilos ? "KiB" : "B",
cpus_str);
virBufferAdjustIndent(&controlBuf, indent + 4);
for (j = 0; j < bank->ncontrols; j++) {
bool min_kilos = !(bank->controls[j]->min % 1024);
virBufferAsprintf(&controlBuf,
"<control min='%llu' unit='%s' "
"type='%s' maxAllocs='%u'/>\n",
bank->controls[j]->min >> (min_kilos * 10),
min_kilos ? "KiB" : "B",
virCacheTypeToString(bank->controls[j]->scope),
bank->controls[j]->max_allocation);
}
if (virBufferUse(&controlBuf)) {
virBufferAddLit(buf, ">\n");
virBufferAddBuffer(buf, &controlBuf);
virBufferAddLit(buf, "</bank>\n");
} else {
virBufferAddLit(buf, "/>\n");
}
VIR_FREE(cpus_str);
}
......@@ -1519,13 +1543,115 @@ virCapsHostCacheBankEquals(virCapsHostCacheBankPtr a,
void
virCapsHostCacheBankFree(virCapsHostCacheBankPtr ptr)
{
size_t i;
if (!ptr)
return;
virBitmapFree(ptr->cpus);
for (i = 0; i < ptr->ncontrols; i++)
VIR_FREE(ptr->controls[i]);
VIR_FREE(ptr->controls);
VIR_FREE(ptr);
}
/*
* This function tests which TYPE of cache control is supported
* Return values are:
* -1: not supported
* 0: CAT
* 1: CDP
*/
static int
virCapabilitiesGetCacheControlType(virCapsHostCacheBankPtr bank)
{
int ret = -1;
char *path = NULL;
if (virAsprintf(&path,
SYSFS_RESCTRL_PATH "/info/L%u",
bank->level) < 0)
return -1;
if (virFileExists(path)) {
ret = 0;
} else {
VIR_FREE(path);
/*
* If CDP is enabled, there will be both CODE and DATA, but it's enough
* to check one of those only.
*/
if (virAsprintf(&path,
SYSFS_RESCTRL_PATH "/info/L%uCODE",
bank->level) < 0)
return -1;
if (virFileExists(path))
ret = 1;
}
VIR_FREE(path);
return ret;
}
static int
virCapabilitiesGetCacheControl(virCapsHostCacheBankPtr bank,
virCacheType scope)
{
int ret = -1;
char *path = NULL;
char *cbm_mask = NULL;
char *type_upper = NULL;
unsigned int min_cbm_bits = 0;
virCapsHostCacheControlPtr control;
if (VIR_ALLOC(control) < 0)
goto cleanup;
if (scope != VIR_CACHE_TYPE_BOTH &&
virStringToUpper(&type_upper, virCacheTypeToString(scope)) < 0)
goto cleanup;
if (virFileReadValueUint(&control->max_allocation,
SYSFS_RESCTRL_PATH "/info/L%u%s/num_closids",
bank->level,
type_upper ? type_upper : "") < 0)
goto cleanup;
if (virFileReadValueString(&cbm_mask,
SYSFS_RESCTRL_PATH
"/info/L%u%s/cbm_mask",
bank->level,
type_upper ? type_upper: "") < 0)
goto cleanup;
if (virFileReadValueUint(&min_cbm_bits,
SYSFS_RESCTRL_PATH "/info/L%u%s/min_cbm_bits",
bank->level,
type_upper ? type_upper : "") < 0)
goto cleanup;
virStringTrimOptionalNewline(cbm_mask);
/* cbm_mask: cache bit mask, it's in hex, eg: fffff */
control->min = min_cbm_bits * bank->size / (strlen(cbm_mask) * 4);
control->scope = scope;
if (VIR_APPEND_ELEMENT(bank->controls,
bank->ncontrols,
control) < 0)
goto cleanup;
ret = 0;
cleanup:
VIR_FREE(path);
VIR_FREE(cbm_mask);
VIR_FREE(type_upper);
VIR_FREE(control);
return ret;
}
int
virCapabilitiesInitCaches(virCapsPtr caps)
{
......@@ -1534,6 +1660,7 @@ virCapabilitiesInitCaches(virCapsPtr caps)
ssize_t pos = -1;
DIR *dirp = NULL;
int ret = -1;
int typeret;
char *path = NULL;
char *type = NULL;
struct dirent *ent = NULL;
......@@ -1609,12 +1736,27 @@ virCapabilitiesInitCaches(virCapsPtr caps)
SYSFS_SYSTEM_PATH, pos, ent->d_name) < 0)
goto cleanup;
typeret = virCapabilitiesGetCacheControlType(bank);
if (typeret == 0) {
if (virCapabilitiesGetCacheControl(bank,
VIR_CACHE_TYPE_BOTH) < 0)
goto cleanup;
} else if (typeret == 1) {
if (virCapabilitiesGetCacheControl(bank,
VIR_CACHE_TYPE_CODE) < 0 ||
virCapabilitiesGetCacheControl(bank,
VIR_CACHE_TYPE_DATA) < 0)
goto cleanup;
}
kernel_type = virCacheKernelTypeFromString(type);
if (kernel_type < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Unknown cache type '%s'"), type);
goto cleanup;
}
bank->type = kernel_type;
VIR_FREE(type);
......
......@@ -148,6 +148,14 @@ typedef enum {
VIR_ENUM_DECL(virCache);
typedef struct _virCapsHostCacheControl virCapsHostCacheControl;
typedef virCapsHostCacheControl *virCapsHostCacheControlPtr;
struct _virCapsHostCacheControl {
unsigned long long min; /* minimum cache control size in B */
virCacheType scope; /* data, code or both */
unsigned int max_allocation; /* max number of supported allocations */
};
typedef struct _virCapsHostCacheBank virCapsHostCacheBank;
typedef virCapsHostCacheBank *virCapsHostCacheBankPtr;
struct _virCapsHostCacheBank {
......@@ -156,6 +164,8 @@ struct _virCapsHostCacheBank {
unsigned long long size; /* B */
virCacheType type; /* Data, Instruction or Unified */
virBitmapPtr cpus; /* All CPUs that share this bank */
size_t ncontrols;
virCapsHostCacheControlPtr *controls;
};
typedef struct _virCapsHost virCapsHost;
......
L3DATA:0=fffff;1=fffff
L3CODE:0=fffff;1=fffff
../linux-resctrl/system/
\ No newline at end of file
<capabilities>
<host>
<cpu>
<arch>x86_64</arch>
</cpu>
<power_management/>
<migration_features>
<live/>
</migration_features>
<topology>
<cells num='2'>
<cell id='0'>
<memory unit='KiB'>1048576</memory>
<pages unit='KiB' size='4'>2048</pages>
<pages unit='KiB' size='2048'>4096</pages>
<pages unit='KiB' size='1048576'>6144</pages>
<cpus num='6'>
<cpu id='0' socket_id='0' core_id='0' siblings='0'/>
<cpu id='1' socket_id='0' core_id='1' siblings='1'/>
<cpu id='2' socket_id='0' core_id='2' siblings='2'/>
<cpu id='3' socket_id='0' core_id='3' siblings='3'/>
<cpu id='4' socket_id='0' core_id='4' siblings='4'/>
<cpu id='5' socket_id='0' core_id='5' siblings='5'/>
</cpus>
</cell>
<cell id='1'>
<memory unit='KiB'>2097152</memory>
<pages unit='KiB' size='4'>4096</pages>
<pages unit='KiB' size='2048'>6144</pages>
<pages unit='KiB' size='1048576'>8192</pages>
<cpus num='6'>
<cpu id='6' socket_id='1' core_id='0' siblings='6'/>
<cpu id='7' socket_id='1' core_id='1' siblings='7'/>
<cpu id='8' socket_id='1' core_id='2' siblings='8'/>
<cpu id='9' socket_id='1' core_id='3' siblings='9'/>
<cpu id='10' socket_id='1' core_id='4' siblings='10'/>
<cpu id='11' socket_id='1' core_id='5' siblings='11'/>
</cpus>
</cell>
</cells>
</topology>
<cache>
<bank id='0' level='3' type='both' size='15360' unit='KiB' cpus='0-5'>
<control min='768' unit='KiB' type='code' maxAllocs='8'/>
<control min='768' unit='KiB' type='data' maxAllocs='8'/>
</bank>
<bank id='1' level='3' type='both' size='15360' unit='KiB' cpus='6-11'>
<control min='768' unit='KiB' type='code' maxAllocs='8'/>
<control min='768' unit='KiB' type='data' maxAllocs='8'/>
</bank>
</cache>
</host>
</capabilities>
......@@ -41,8 +41,12 @@
</cells>
</topology>
<cache>
<bank id='0' level='3' type='both' size='15360' unit='KiB' cpus='0-5'/>
<bank id='1' level='3' type='both' size='15360' unit='KiB' cpus='6-11'/>
<bank id='0' level='3' type='both' size='15360' unit='KiB' cpus='0-5'>
<control min='1536' unit='KiB' type='both' maxAllocs='4'/>
</bank>
<bank id='1' level='3' type='both' size='15360' unit='KiB' cpus='6-11'>
<control min='1536' unit='KiB' type='both' maxAllocs='4'/>
</bank>
</cache>
</host>
......
......@@ -47,6 +47,7 @@ test_virCapabilities(const void *opaque)
char *capsXML = NULL;
char *path = NULL;
char *dir = NULL;
char *resctrl = NULL;
int ret = -1;
/*
......@@ -58,7 +59,12 @@ test_virCapabilities(const void *opaque)
data->resctrl ? "/system" : "") < 0)
goto cleanup;
if (virAsprintf(&resctrl, "%s/vircaps2xmldata/linux-%s/resctrl",
abs_srcdir, data->filename) < 0)
goto cleanup;
virFileWrapperAddPrefix("/sys/devices/system", dir);
virFileWrapperAddPrefix("/sys/fs/resctrl", resctrl);
caps = virCapabilitiesNew(data->arch, data->offlineMigrate, data->liveMigrate);
if (!caps)
......@@ -84,6 +90,7 @@ test_virCapabilities(const void *opaque)
cleanup:
VIR_FREE(dir);
VIR_FREE(resctrl);
VIR_FREE(path);
VIR_FREE(capsXML);
virObjectUnref(caps);
......@@ -112,6 +119,7 @@ mymain(void)
DO_TEST("caches", VIR_ARCH_X86_64);
DO_TEST_FULL("resctrl", VIR_ARCH_X86_64, true, true, true);
DO_TEST_FULL("resctrl-cdp", VIR_ARCH_X86_64, true, true, true);
return ret;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册