Skip to content

Commit

Permalink
asdf
Browse files Browse the repository at this point in the history
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
  • Loading branch information
nertpinx committed Mar 27, 2017
1 parent ce862a2 commit c335de4
Show file tree
Hide file tree
Showing 8 changed files with 376 additions and 8 deletions.
140 changes: 139 additions & 1 deletion src/conf/capabilities.c
Expand Up @@ -861,6 +861,41 @@ virCapabilitiesFormatNUMATopology(virBufferPtr buf,
return 0;
}

static int
virCapabilitiesFormatCaches(virBufferPtr buf,
size_t ncaches,
virCapsHostCacheBankPtr caches)
{
size_t i = 0;
virBuffer childrenBuf = VIR_BUFFER_INITIALIZER;

for (i = 0; i < ncaches; i++) {
virCapsHostCacheBankPtr bank = caches + i;
char *cpus_str = virBitmapFormat(bank->cpus);

if (!cpus_str) {
virBufferFreeAndReset(&childrenBuf);
return -1;
}

virBufferAsprintf(&childrenBuf,
"<bank id='%u' level='%u' type='%s' size='%llu' unit? cpus='%s'>\n",
bank->id, bank->level, Junit
virCacheTypeToString(bank->type),
bank->size, cpus_str);
}

if (virBufferUse(&childrenBuf)) {
virBufferAddLit(buf, "<cache>\n");
virBufferAdjustIndent(buf, 2);
virBufferAddBuffer(buf, &childrenBuf);
virBufferAdjustIndent(buf, -2);
virBufferAddLit(buf, "</cache>\n");
}

return 0;
}

/**
* virCapabilitiesFormatXML:
* @caps: capabilities to format
Expand Down Expand Up @@ -955,7 +990,11 @@ virCapabilitiesFormatXML(virCapsPtr caps)
if (caps->host.nnumaCell &&
virCapabilitiesFormatNUMATopology(&buf, caps->host.nnumaCell,
caps->host.numaCell) < 0)
return NULL;
goto error;

if (virCapabilitiesFormatCaches(&buf, caps->host.ncaches,
caps->host.caches) < 0)
goto error;

for (i = 0; i < caps->host.nsecModels; i++) {
virBufferAddLit(&buf, "<secmodel>\n");
Expand Down Expand Up @@ -1072,6 +1111,10 @@ virCapabilitiesFormatXML(virCapsPtr caps)
return NULL;

return virBufferContentAndReset(&buf);

error:
virBufferFreeAndReset(&buf);
return NULL;
}

/* get the maximum ID of cpus in the host */
Expand Down Expand Up @@ -1435,3 +1478,98 @@ virCapabilitiesInitPages(virCapsPtr caps)
VIR_FREE(pages_size);
return ret;
}


VIR_ENUM_IMPL(virCache, VIR_CACHE_TYPE_LAST,
"Data",
"Instruction",
"Unified")

bool
virCapsHostCacheBankEquals(virCapsHostCacheBankPtr a,
virCapsHostCacheBankPtr b)
{
return (a->id == b->id &&
a->level == b->level &&
a->type == b->type &&
a->size == b->size &&
virBitmapEqual(a->cpus, b->cpus));

}

void
virCapsHostCacheBankFree(virCapsHostCacheBankPtr ptr)
{
if (!ptr)
return;

virBitmapFree(ptr->cpus);
VIR_FREE(ptr);
}

int
virCapabilitiesInitCaches(virCapsPtr caps)
{
size_t i = 0;
virBitmapPtr cpus = NULL;
ssize_t pos = -1;
DIR *dirp = NULL;
int ret = -1;
char *type = NULL;
struct dirent *ent = NULL;
virCapsHostCacheBankPtr bank = NULL;

/* offline CPUs don't provide cache info */
if (virSysfsGetValueBitmap("cpu/online", &cpus) < 0)
return -1;

while ((pos = virBitmapNextSetBit(cpus, pos)) >= 0) {
int rv = virSysfsCpuDirOpen(pos, "cache/", &dirp);

if (rv == -2)
continue;

while ((rv = virDirRead(dirp, &ent, "cache/")) > 0) {
int tmp;

if (!STRPREFIX(ent->d_name, "index"))
continue;

if (VIR_ALLOC(bank) < 0)
goto cleanup;

if (virSysfsGetCpuCacheValueUint(pos, ent->d_name, "id", &bank->id) < 0 ||
virSysfsGetCpuCacheValueUint(pos, ent->d_name, "level", &bank->level) < 0 ||
virSysfsGetCpuCacheValueString(pos, ent->d_name, "type", &type) < 0 ||
virSysfsGetCpuCacheValueUint(pos, ent->d_name, "size", &bank->size) < 0 ||
virSysfsGetCpuCacheValueBitmap(pos, ent->d_name, "shared_cpu_map", &bank->cpus) < 0)
goto cleanup;

tmp = virCacheTypeFromString(type);
if (tmp < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Unknown cache type '%s'"), type);
VIR_FREE(type);
goto cleanup;
}

for (i = 0; i < caps->host.ncaches; i++) {
if (virCapsHostCacheBankEquals(bank, caps->host.caches + i))
continue;
}

if (VIR_APPEND_ELEMENT(caps->host.caches,
caps->host.ncaches,
*bank) < 0) {
goto cleanup;
}
}
if (rv < 0)
goto cleanup;
}

cleanup:
virDirClose(&dirp);
virCapsHostCacheBankFree(bank);
return ret;
}
29 changes: 29 additions & 0 deletions src/conf/capabilities.h
Expand Up @@ -138,6 +138,26 @@ struct _virCapsHostSecModel {
virCapsHostSecModelLabelPtr labels;
};

typedef enum {
VIR_CACHE_TYPE_DATA,
VIR_CACHE_TYPE_INSTRUCTION,
VIR_CACHE_TYPE_UNIFIED,

VIR_CACHE_TYPE_LAST
} virCacheType;

VIR_ENUM_DECL(virCache);

typedef struct _virCapsHostCacheBank virCapsHostCacheBank;
typedef virCapsHostCacheBank *virCapsHostCacheBankPtr;
struct _virCapsHostCacheBank {
unsigned int id;
unsigned int level; /* 1=L1, 2=L2, 3=L3, etc. */
unsigned long long size; /* KiB */
virCacheType type; /* Data, Instruction or Unified */
virBitmapPtr cpus; /* All CPUs that share this bank */
};

typedef struct _virCapsHost virCapsHost;
typedef virCapsHost *virCapsHostPtr;
struct _virCapsHost {
Expand All @@ -157,6 +177,9 @@ struct _virCapsHost {
size_t nnumaCell_max;
virCapsHostNUMACellPtr *numaCell;

size_t ncaches;
virCapsHostCacheBankPtr caches;

size_t nsecModels;
virCapsHostSecModelPtr secModels;

Expand Down Expand Up @@ -303,4 +326,10 @@ int virCapabilitiesInitPages(virCapsPtr caps);

int virCapabilitiesInitNUMA(virCapsPtr caps);

bool virCapsHostCacheBankEquals(virCapsHostCacheBankPtr a,
virCapsHostCacheBankPtr b);
void virCapsHostCacheBankFree(virCapsHostCacheBankPtr ptr);

int virCapabilitiesInitCaches(virCapsPtr caps);

#endif /* __VIR_CAPABILITIES_H */
3 changes: 3 additions & 0 deletions src/libvirt_private.syms
Expand Up @@ -59,6 +59,7 @@ virCapabilitiesFreeNUMAInfo;
virCapabilitiesGetCpusForNodemask;
virCapabilitiesGetNodeInfo;
virCapabilitiesHostSecModelAddBaseLabel;
virCapabilitiesInitCaches;
virCapabilitiesInitNUMA;
virCapabilitiesInitPages;
virCapabilitiesNew;
Expand Down Expand Up @@ -1631,6 +1632,7 @@ virFileReadLimFD;
virFileReadLink;
virFileReadValueBitmap;
virFileReadValueInt;
virFileReadValueScaledInt;
virFileReadValueUint;
virFileRelLinkPointsTo;
virFileRemove;
Expand Down Expand Up @@ -2620,6 +2622,7 @@ virVasprintfInternal;


# util/virsysfs.h
virSysfsCpuDirOpen;
virSysfsGetCpuValueBitmap;
virSysfsGetCpuValueInt;
virSysfsGetCpuValueString;
Expand Down
29 changes: 27 additions & 2 deletions src/util/virfile.c
Expand Up @@ -2861,11 +2861,11 @@ virDirOpenQuiet(DIR **dirp, const char *name)
/**
* virDirRead:
* @dirp: directory to read
* @end: output one entry
* @ent: output one entry
* @name: if non-NULL, the name related to @dirp for use in error reporting
*
* Wrapper around readdir. Typical usage:
* struct dirent ent;
* struct dirent *ent;
* int rc;
* DIR *dir;
* if (virDirOpen(&dir, name) < 0)
Expand Down Expand Up @@ -3879,6 +3879,31 @@ virFileReadValueUint(const char *path, unsigned int *value)
* Return -2 for non-existing file, -1 on other errors and 0 if everything went
* fine.
*/
int
virFileReadValueScaledInt(const char *path, unsigned long long *value)
{
char *str = NULL;
char *endp = NULL;

if (!virFileExists(path))
return -2;

if (virFileReadAll(path, INT_STRLEN_BOUND(*value), &str) < 0)
return -1;

if (virStrToLong_ullp(str, &endp, 10, value) < 0 ||
virScaleInteger(value, endp, 1024, ULLONG_MAX) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Invalid unsigned scaled integer value '%s' in file '%s'"),
str, path);
return -1;
}

VIR_FREE(str);

return 0;
}

int
virFileReadValueBitmap(const char *path,
int maxlen,
Expand Down
1 change: 1 addition & 0 deletions src/util/virfile.h
Expand Up @@ -338,6 +338,7 @@ int virFileComparePaths(const char *p1, const char *p2);

int virFileReadValueInt(const char *path, int *value);
int virFileReadValueUint(const char *path, unsigned int *value);
int virFileReadValueScaledInt(const char *path, unsigned long long *value);
int virFileReadValueBitmap(const char *path, int maxlen, virBitmapPtr *value);

#endif /* __VIR_FILE_H */

0 comments on commit c335de4

Please sign in to comment.