#include <unistd.h>
#include "capabilities.h"
+#include "c-ctype.h"
#include "count-one-bits.h"
#include "cpu_conf.h"
#include "domain_conf.h"
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 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,
- "<control min='%llu' unit='%s' "
- "type='%s' maxAllocs='%u'/>\n",
- bank->controls[j]->min >> (min_kilos * 10),
+ " unit='%s' type='%s' maxAllocs='%u'/>\n",
min_kilos ? "KiB" : "B",
virCacheTypeToString(bank->controls[j]->scope),
bank->controls[j]->max_allocation);
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;
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;
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;
</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>
--- /dev/null
+<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>
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;
}