mirror of https://gitee.com/openkylin/libvirt.git
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: Eli Qiao <liyong.qiao@intel.com>
This commit is contained in:
parent
7b4e9b2c55
commit
0ab409ccc4
|
@ -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;
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
ffffff,ffffffff,ffffffff
|
|
@ -0,0 +1 @@
|
|||
fffff
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1 @@
|
|||
8
|
|
@ -0,0 +1 @@
|
|||
fffff
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1 @@
|
|||
8
|
|
@ -0,0 +1 @@
|
|||
000000,00000000,00000000
|
|
@ -0,0 +1,2 @@
|
|||
L3DATA:0=c0000;1=c0000
|
||||
L3CODE:0=30000;1=30000
|
|
@ -0,0 +1,2 @@
|
|||
L3DATA:0=fffff;1=fffff
|
||||
L3CODE:0=fffff;1=fffff
|
|
@ -0,0 +1 @@
|
|||
../linux-resctrl/system/
|
|
@ -0,0 +1,55 @@
|
|||
<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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue