Report more correct information for cache control

On some platforms the number of bits in the cbm_mask might not be
divisible by 4 (and not even by 2), so we need to properly count the
bits.  Similar file, min_cbm_bits, is properly parsed and used, but if
the number is greater than one, we lose the information about
granularity when reporting the data in capabilities.  For that matter
always report granularity, but if it is not the same as the minimum,
add that information in there as well.

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
This commit is contained in:
Martin Kletzander 2017-06-05 14:00:45 +02:00
parent ba326c8699
commit cc9f0521cd
31 changed files with 104 additions and 16 deletions

View File

@ -273,9 +273,14 @@
</attribute>
<zeroOrMore>
<element name='control'>
<attribute name='min'>
<attribute name='granularity'>
<ref name='unsignedInt'/>
</attribute>
<optional>
<attribute name='min'>
<ref name='unsignedInt'/>
</attribute>
</optional>
<attribute name='unit'>
<ref name='unit'/>
</attribute>

View File

@ -31,6 +31,7 @@
#include <unistd.h>
#include "capabilities.h"
#include "c-ctype.h"
#include "count-one-bits.h"
#include "cpu_conf.h"
#include "domain_conf.h"
@ -906,11 +907,24 @@ virCapabilitiesFormatCaches(virBufferPtr buf,
virBufferAdjustIndent(&controlBuf, indent + 4);
for (j = 0; j < bank->ncontrols; j++) {
bool min_kilos = !(bank->controls[j]->min % 1024);
bool min_kilos = !(bank->controls[j]->granularity % 1024);
/* Only use KiB if both values are divisible */
if (bank->controls[j]->min)
min_kilos = 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),
"<control granularity='%llu'",
bank->controls[j]->granularity >> (min_kilos * 10));
if (bank->controls[j]->min) {
virBufferAsprintf(&controlBuf,
" min='%llu'",
bank->controls[j]->min >> (min_kilos * 10));
}
virBufferAsprintf(&controlBuf,
" unit='%s' type='%s' maxAllocs='%u'/>\n",
min_kilos ? "KiB" : "B",
virCacheTypeToString(bank->controls[j]->scope),
bank->controls[j]->max_allocation);
@ -1598,9 +1612,11 @@ virCapabilitiesGetCacheControl(virCapsHostCacheBankPtr bank,
virCacheType scope)
{
int ret = -1;
char *tmp = NULL;
char *path = NULL;
char *cbm_mask = NULL;
char *type_upper = NULL;
unsigned int bits = 0;
unsigned int min_cbm_bits = 0;
virCapsHostCacheControlPtr control;
@ -1632,8 +1648,14 @@ virCapabilitiesGetCacheControl(virCapsHostCacheBankPtr bank,
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);
for (tmp = cbm_mask; *tmp != '\0'; tmp++) {
if (c_isxdigit(*tmp))
bits += count_one_bits(virHexToBin(*tmp));
}
control->granularity = bank->size / bits;
if (min_cbm_bits != 1)
control->min = min_cbm_bits * control->granularity;
control->scope = scope;

View File

@ -151,9 +151,14 @@ 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 */
/* Smallest possible increase of the allocation size in bytes */
unsigned long long granularity;
/* Minimal allocatable size in bytes (if different from granularity) */
unsigned long long min;
/* Type of the allocation */
virCacheType scope;
/* Maximum number of simultaneous allocations */
unsigned int max_allocation;
};
typedef struct _virCapsHostCacheBank virCapsHostCacheBank;

View File

@ -0,0 +1 @@
7ff

View File

@ -0,0 +1 @@
L3:0=7ff;1=7ff

View File

@ -0,0 +1 @@
0

View File

@ -0,0 +1 @@
3

View File

@ -0,0 +1 @@
33M

View File

@ -0,0 +1 @@
Unified

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1 @@
0

View File

@ -0,0 +1 @@
0

View File

@ -0,0 +1 @@
../../cpu/cpu0

View File

@ -0,0 +1 @@
001

View File

@ -0,0 +1 @@
0

View File

@ -42,12 +42,12 @@
</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'/>
<control granularity='768' unit='KiB' type='code' maxAllocs='8'/>
<control granularity='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'/>
<control granularity='768' unit='KiB' type='code' maxAllocs='8'/>
<control granularity='768' unit='KiB' type='data' maxAllocs='8'/>
</bank>
</cache>
</host>

View File

@ -0,0 +1,31 @@
<capabilities>
<host>
<cpu>
<arch>x86_64</arch>
</cpu>
<power_management/>
<migration_features>
<live/>
</migration_features>
<topology>
<cells num='1'>
<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='1'>
<cpu id='0' socket_id='0' core_id='0' siblings='0'/>
</cpus>
</cell>
</cells>
</topology>
<cache>
<bank id='0' level='3' type='both' size='33792' unit='KiB' cpus='0'>
<control granularity='3072' unit='KiB' type='both' maxAllocs='16'/>
</bank>
</cache>
</host>
</capabilities>

View File

@ -42,10 +42,10 @@
</topology>
<cache>
<bank id='0' level='3' type='both' size='15360' unit='KiB' cpus='0-5'>
<control min='1536' unit='KiB' type='both' maxAllocs='4'/>
<control granularity='768' 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'/>
<control granularity='768' min='1536' unit='KiB' type='both' maxAllocs='4'/>
</bank>
</cache>
</host>

View File

@ -120,6 +120,7 @@ mymain(void)
DO_TEST_FULL("resctrl", VIR_ARCH_X86_64, true, true, true);
DO_TEST_FULL("resctrl-cdp", VIR_ARCH_X86_64, true, true, true);
DO_TEST_FULL("resctrl-skx", VIR_ARCH_X86_64, true, true, true);
return ret;
}