mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 13:45:38 +00:00
Move resctrl-related code from conf/capabilities to util/virresctrl
It doesn't access anything from conf/ and ti will be needed to use from other util/ places. This split makes the separation clearer. Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
This commit is contained in:
parent
ab0e027ffe
commit
af4270400a
@ -132,6 +132,7 @@ typedef enum {
|
||||
|
||||
VIR_FROM_PERF = 65, /* Error from perf */
|
||||
VIR_FROM_LIBSSH = 66, /* Error from libssh connection transport */
|
||||
VIR_FROM_RESCTRL = 67, /* Error from resource control */
|
||||
|
||||
# ifdef VIR_ENUM_SENTINELS
|
||||
VIR_ERR_DOMAIN_LAST
|
||||
|
@ -167,6 +167,7 @@ UTIL_SOURCES = \
|
||||
util/virprocess.c util/virprocess.h \
|
||||
util/virqemu.c util/virqemu.h \
|
||||
util/virrandom.h util/virrandom.c \
|
||||
util/virresctrl.h util/virresctrl.c \
|
||||
util/virrotatingfile.h util/virrotatingfile.c \
|
||||
util/virscsi.c util/virscsi.h \
|
||||
util/virscsihost.c util/virscsihost.h \
|
||||
|
@ -31,8 +31,6 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "capabilities.h"
|
||||
#include "c-ctype.h"
|
||||
#include "count-one-bits.h"
|
||||
#include "cpu_conf.h"
|
||||
#include "domain_conf.h"
|
||||
#include "physmem.h"
|
||||
@ -52,7 +50,6 @@
|
||||
#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")
|
||||
|
||||
@ -1539,12 +1536,6 @@ VIR_ENUM_IMPL(virCacheKernel, VIR_CACHE_TYPE_LAST,
|
||||
"Instruction",
|
||||
"Data")
|
||||
|
||||
/* Our naming for cache types and scopes */
|
||||
VIR_ENUM_IMPL(virCache, VIR_CACHE_TYPE_LAST,
|
||||
"both",
|
||||
"code",
|
||||
"data")
|
||||
|
||||
bool
|
||||
virCapsHostCacheBankEquals(virCapsHostCacheBankPtr a,
|
||||
virCapsHostCacheBankPtr b)
|
||||
@ -1571,111 +1562,6 @@ virCapsHostCacheBankFree(virCapsHostCacheBankPtr ptr)
|
||||
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 *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;
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
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)
|
||||
{
|
||||
@ -1760,17 +1646,27 @@ virCapabilitiesInitCaches(virCapsPtr caps)
|
||||
SYSFS_SYSTEM_PATH, pos, ent->d_name) < 0)
|
||||
goto cleanup;
|
||||
|
||||
typeret = virCapabilitiesGetCacheControlType(bank);
|
||||
typeret = virResctrlGetCacheControlType(bank->level);
|
||||
|
||||
if (typeret == 0) {
|
||||
if (virCapabilitiesGetCacheControl(bank,
|
||||
VIR_CACHE_TYPE_BOTH) < 0)
|
||||
if (virResctrlGetCacheInfo(bank->level,
|
||||
bank->size,
|
||||
VIR_CACHE_TYPE_BOTH,
|
||||
&bank->controls,
|
||||
&bank->ncontrols) < 0)
|
||||
goto cleanup;
|
||||
} else if (typeret == 1) {
|
||||
if (virCapabilitiesGetCacheControl(bank,
|
||||
VIR_CACHE_TYPE_CODE) < 0 ||
|
||||
virCapabilitiesGetCacheControl(bank,
|
||||
VIR_CACHE_TYPE_DATA) < 0)
|
||||
if (virResctrlGetCacheInfo(bank->level,
|
||||
bank->size,
|
||||
VIR_CACHE_TYPE_CODE,
|
||||
&bank->controls,
|
||||
&bank->ncontrols) < 0)
|
||||
goto cleanup;
|
||||
if (virResctrlGetCacheInfo(bank->level,
|
||||
bank->size,
|
||||
VIR_CACHE_TYPE_DATA,
|
||||
&bank->controls,
|
||||
&bank->ncontrols) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
# include "virarch.h"
|
||||
# include "virmacaddr.h"
|
||||
# include "virobject.h"
|
||||
# include "virresctrl.h"
|
||||
|
||||
# include <libxml/xpath.h>
|
||||
|
||||
@ -138,29 +139,6 @@ struct _virCapsHostSecModel {
|
||||
virCapsHostSecModelLabelPtr labels;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
VIR_CACHE_TYPE_BOTH,
|
||||
VIR_CACHE_TYPE_CODE,
|
||||
VIR_CACHE_TYPE_DATA,
|
||||
|
||||
VIR_CACHE_TYPE_LAST
|
||||
} virCacheType;
|
||||
|
||||
VIR_ENUM_DECL(virCache);
|
||||
|
||||
typedef struct _virCapsHostCacheControl virCapsHostCacheControl;
|
||||
typedef virCapsHostCacheControl *virCapsHostCacheControlPtr;
|
||||
struct _virCapsHostCacheControl {
|
||||
/* 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;
|
||||
typedef virCapsHostCacheBank *virCapsHostCacheBankPtr;
|
||||
struct _virCapsHostCacheBank {
|
||||
@ -170,7 +148,7 @@ struct _virCapsHostCacheBank {
|
||||
virCacheType type; /* Data, Instruction or Unified */
|
||||
virBitmapPtr cpus; /* All CPUs that share this bank */
|
||||
size_t ncontrols;
|
||||
virCapsHostCacheControlPtr *controls;
|
||||
virResctrlPtr *controls;
|
||||
};
|
||||
|
||||
typedef struct _virCapsHost virCapsHost;
|
||||
|
@ -2465,6 +2465,13 @@ virRandomGenerateWWN;
|
||||
virRandomInt;
|
||||
|
||||
|
||||
# util/virresctrl.h
|
||||
virCacheTypeFromString;
|
||||
virCacheTypeToString;
|
||||
virResctrlGetCacheControlType;
|
||||
virResctrlGetCacheInfo;
|
||||
|
||||
|
||||
# util/virrotatingfile.h
|
||||
virRotatingFileReaderConsume;
|
||||
virRotatingFileReaderFree;
|
||||
|
@ -139,6 +139,7 @@ VIR_ENUM_IMPL(virErrorDomain, VIR_ERR_DOMAIN_LAST,
|
||||
|
||||
"Perf", /* 65 */
|
||||
"Libssh transport layer",
|
||||
"Resource control",
|
||||
)
|
||||
|
||||
|
||||
|
153
src/util/virresctrl.c
Normal file
153
src/util/virresctrl.c
Normal file
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* virresctrl.c:
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "virresctrl.h"
|
||||
|
||||
#include "c-ctype.h"
|
||||
#include "count-one-bits.h"
|
||||
#include "viralloc.h"
|
||||
#include "virfile.h"
|
||||
#include "virlog.h"
|
||||
#include "virstring.h"
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_RESCTRL
|
||||
|
||||
VIR_LOG_INIT("util.virresctrl")
|
||||
|
||||
#define SYSFS_RESCTRL_PATH "/sys/fs/resctrl"
|
||||
|
||||
/* Resctrl is short for Resource Control. It might be implemented for various
|
||||
* resources, but at the time of this writing this is only supported for cache
|
||||
* allocation technology (aka CAT). Hence the reson for leaving 'Cache' out of
|
||||
* all the structure and function names for now (can be added later if needed.
|
||||
*/
|
||||
|
||||
/* Our naming for cache types and scopes */
|
||||
VIR_ENUM_IMPL(virCache, VIR_CACHE_TYPE_LAST,
|
||||
"both",
|
||||
"code",
|
||||
"data")
|
||||
|
||||
int
|
||||
virResctrlGetCacheInfo(unsigned int level,
|
||||
unsigned long long size,
|
||||
virCacheType scope,
|
||||
virResctrlPtr **controls,
|
||||
size_t *ncontrols)
|
||||
{
|
||||
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;
|
||||
virResctrlPtr 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",
|
||||
level,
|
||||
type_upper ? type_upper : "") < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (virFileReadValueString(&cbm_mask,
|
||||
SYSFS_RESCTRL_PATH
|
||||
"/info/L%u%s/cbm_mask",
|
||||
level,
|
||||
type_upper ? type_upper: "") < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (virFileReadValueUint(&min_cbm_bits,
|
||||
SYSFS_RESCTRL_PATH "/info/L%u%s/min_cbm_bits",
|
||||
level,
|
||||
type_upper ? type_upper : "") < 0)
|
||||
goto cleanup;
|
||||
|
||||
virStringTrimOptionalNewline(cbm_mask);
|
||||
|
||||
for (tmp = cbm_mask; *tmp != '\0'; tmp++) {
|
||||
if (c_isxdigit(*tmp))
|
||||
bits += count_one_bits(virHexToBin(*tmp));
|
||||
}
|
||||
|
||||
control->granularity = size / bits;
|
||||
if (min_cbm_bits != 1)
|
||||
control->min = min_cbm_bits * control->granularity;
|
||||
|
||||
control->scope = scope;
|
||||
|
||||
if (VIR_APPEND_ELEMENT(*controls, *ncontrols, control) < 0)
|
||||
goto cleanup;
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
VIR_FREE(path);
|
||||
VIR_FREE(cbm_mask);
|
||||
VIR_FREE(type_upper);
|
||||
VIR_FREE(control);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function tests which TYPE of cache control is supported
|
||||
* Return values are:
|
||||
* -1: not supported
|
||||
* 0: CAT
|
||||
* 1: CDP
|
||||
*/
|
||||
int
|
||||
virResctrlGetCacheControlType(unsigned int level)
|
||||
{
|
||||
int ret = -1;
|
||||
char *path = NULL;
|
||||
|
||||
if (virAsprintf(&path,
|
||||
SYSFS_RESCTRL_PATH "/info/L%u",
|
||||
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",
|
||||
level) < 0)
|
||||
return -1;
|
||||
if (virFileExists(path))
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
VIR_FREE(path);
|
||||
return ret;
|
||||
}
|
63
src/util/virresctrl.h
Normal file
63
src/util/virresctrl.h
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* virresctrl.h:
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __VIR_RESCTRL_H__
|
||||
# define __VIR_RESCTRL_H__
|
||||
|
||||
# include "internal.h"
|
||||
|
||||
# include "virbitmap.h"
|
||||
# include "virutil.h"
|
||||
|
||||
|
||||
typedef enum {
|
||||
VIR_CACHE_TYPE_BOTH,
|
||||
VIR_CACHE_TYPE_CODE,
|
||||
VIR_CACHE_TYPE_DATA,
|
||||
|
||||
VIR_CACHE_TYPE_LAST
|
||||
} virCacheType;
|
||||
|
||||
VIR_ENUM_DECL(virCache);
|
||||
|
||||
|
||||
typedef struct _virResctrl virResctrl;
|
||||
typedef virResctrl *virResctrlPtr;
|
||||
struct _virResctrl {
|
||||
/* 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;
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
virResctrlGetCacheInfo(unsigned int level,
|
||||
unsigned long long size,
|
||||
virCacheType scope,
|
||||
virResctrlPtr **controls,
|
||||
size_t *ncontrols);
|
||||
|
||||
int
|
||||
virResctrlGetCacheControlType(unsigned int level);
|
||||
|
||||
#endif /* __VIR_RESCTRL_H__ */
|
Loading…
Reference in New Issue
Block a user