The resctrl default allocation is introduced in this patch,
which refers to the root directory (/sys/fs/resctrl) and
immediately be created after mounting, owns all the tasks
and cpus in the system and can make full use of all resources.
It does not intentionally allocate any dedicated amount
of resource, either cache or memory bandwidth, for default
allocation.
If a system task has no resource control applied but you
want to know task's cache or memroy bandwidth utilization
information, the default allocation is meaningful. We create
resctrl monitor under the default allocation for such kind of
task.
Refactoring schemas docs and APIs to create a default
cache allocation by allowing the appearance of an
<cachetune> with no <cache> element.
Signed-off-by: Wang Huaqiang <huaqiang.wang(a)intel.com>
---
docs/formatdomain.html.in | 4 ++--
docs/schemas/domaincommon.rng | 4 ++--
src/conf/domain_conf.c | 32 +++++++++++++++++++-------------
src/util/virresctrl.c | 27 +++++++++++++++++++++++++++
4 files changed, 50 insertions(+), 17 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 8189959..b1651e3 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -943,8 +943,8 @@
<dl>
<dt><code>cache</code></dt>
<dd>
- This element controls the allocation of CPU cache and has the
- following attributes:
+ This optional element controls the allocation of CPU cache and has
+ the following attributes:
<dl>
<dt><code>level</code></dt>
<dd>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 099a949..5c533d6 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -956,7 +956,7 @@
<attribute name="vcpus">
<ref name='cpuset'/>
</attribute>
- <oneOrMore>
+ <zeroOrMore>
<element name="cache">
<attribute name="id">
<ref name='unsignedInt'/>
@@ -980,7 +980,7 @@
</attribute>
</optional>
</element>
- </oneOrMore>
+ </zeroOrMore>
</element>
</zeroOrMore>
<zeroOrMore>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 9911d56..b77680e 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -19002,22 +19002,27 @@ virDomainCachetuneDefParse(virDomainDefPtr def,
goto cleanup;
}
- if (virDomainResctrlVcpuMatch(def, vcpus, &alloc) < 0)
- goto cleanup;
-
- if (!alloc) {
- alloc = virResctrlAllocNew();
- if (!alloc)
+ /* If 'n' equals 0, then no <cache> element found in
<cachetune>,
+ * this means it is a default alloction. For default allocation,
+ * @SetvirDomainResctrlDefPtr->alloc is set to NULL */
+ if (n != 0) {
+ if (virDomainResctrlVcpuMatch(def, vcpus, &alloc) < 0)
goto cleanup;
- } else {
- virReportError(VIR_ERR_XML_ERROR, "%s",
- _("Identical vcpus in cachetunes found"));
- goto cleanup;
- }
- for (i = 0; i < n; i++) {
- if (virDomainCachetuneDefParseCache(ctxt, nodes[i], alloc) < 0)
+ if (!alloc) {
+ alloc = virResctrlAllocNew();
+ if (!alloc)
+ goto cleanup;
+ } else {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("Identical vcpus in cachetunes found"));
goto cleanup;
+ }
+
+ for (i = 0; i < n; i++) {
+ if (virDomainCachetuneDefParseCache(ctxt, nodes[i], alloc) < 0)
+ goto cleanup;
+ }
}
if (virResctrlAllocIsEmpty(alloc)) {
@@ -19027,6 +19032,7 @@ virDomainCachetuneDefParse(virDomainDefPtr def,
if (virDomainResctrlAppend(def, node, alloc, vcpus, flags) < 0)
goto cleanup;
+
vcpus = NULL;
alloc = NULL;
diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c
index df5b512..697424c 100644
--- a/src/util/virresctrl.c
+++ b/src/util/virresctrl.c
@@ -234,6 +234,10 @@ virResctrlInfoMonFree(virResctrlInfoMonPtr mon)
* in case there is no allocation for that particular cache allocation (level,
* cache, ...) or memory allocation for particular node).
*
+ * Resctrl file system root directory, /sys/fs/sysctrl/, is called the default
+ * allocation, which is created, immediately after mounting, owns all the
+ * tasks and cpus in the system and can make full use of all resources.
+ *
* =====Cache allocation technology (CAT)=====
*
* Since one allocation can be made for caches on different levels, the first
@@ -1165,6 +1169,9 @@ virResctrlAllocSetCacheSize(virResctrlAllocPtr alloc,
unsigned int cache,
unsigned long long size)
{
+ if (!alloc)
+ return 0;
+
if (virResctrlAllocCheckCollision(alloc, level, type, cache)) {
virReportError(VIR_ERR_XML_ERROR,
_("Colliding cache allocations for cache "
@@ -1235,6 +1242,9 @@ virResctrlAllocSetMemoryBandwidth(virResctrlAllocPtr alloc,
{
virResctrlAllocMemBWPtr mem_bw = alloc->mem_bw;
+ if (!alloc)
+ return 0;
+
if (memory_bandwidth > 100) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("Memory Bandwidth value exceeding 100 is invalid."));
@@ -1304,6 +1314,11 @@ int
virResctrlAllocSetID(virResctrlAllocPtr alloc,
const char *id)
{
+ /* If passed a default allocation in, @alloc will be NULL. This is
+ * a valid case, return normally. */
+ if (!alloc)
+ return 0;
+
if (!id) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Resctrl allocation 'id' cannot be NULL"));
@@ -1317,6 +1332,9 @@ virResctrlAllocSetID(virResctrlAllocPtr alloc,
const char *
virResctrlAllocGetID(virResctrlAllocPtr alloc)
{
+ if (!alloc)
+ return NULL;
+
return alloc->id;
}
@@ -2209,6 +2227,9 @@ int
virResctrlAllocDeterminePath(virResctrlAllocPtr alloc,
const char *machinename)
{
+ if (!alloc)
+ return 0;
+
if (!alloc->id) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Resctrl Allocation ID must be set before
creation"));
@@ -2302,6 +2323,9 @@ virResctrlAllocAddPID(virResctrlAllocPtr alloc,
char *pidstr = NULL;
int ret = 0;
+ if (!alloc)
+ return 0;
+
if (!alloc->path) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Cannot add pid to non-existing resctrl
allocation"));
@@ -2334,6 +2358,9 @@ virResctrlAllocRemove(virResctrlAllocPtr alloc)
{
int ret = 0;
+ if (!alloc)
+ return 0;
+
if (!alloc->path)
return 0;
--
2.7.4