This patch adds new xml element to support cache tune as:
<cputune>
...
<cachetune cacheId='0' type='both' sizeKiB='2816'
vcpus='0,1'/>
...
</cputune>
cacheId: reference of the host's cache banks id, it's from capabilities
xml.
type: cache bank type, it could be both, code, data.
sizeKiB: must be multiple of granularity, must be greater than or equal
to minimum.
vcpus: cache allocation on vcpu set, if empty, will apply the allocation
on all vcpus.
Signed-off-by: Eli Qiao <liyong.qiao(a)intel.com>
---
docs/schemas/domaincommon.rng | 29 +++++++++++
src/conf/domain_conf.c | 113 +++++++++++++++++++++++++++++++++++++++++-
src/conf/domain_conf.h | 19 +++++++
3 files changed, 160 insertions(+), 1 deletion(-)
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index e259e3e..6e0262e 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -834,6 +834,25 @@
</attribute>
</element>
</zeroOrMore>
+ <zeroOrMore>
+ <element name="cachetune">
+ <attribute name="cacheId">
+ <ref name="cacheid"/>
+ </attribute>
+ <attribute name="type">
+ <ref name="cachetype"/>
+ </attribute>
+ <!-- Cache size is an attribute in KiB, no way to express a unit -->
+ <attribute name="sizeKiB">
+ <ref name="unsignedLong"/>
+ </attribute>
+ <optional>
+ <attribute name="vcpus">
+ <ref name="cpuset"/>
+ </attribute>
+ </optional>
+ </element>
+ </zeroOrMore>
<optional>
<element name="emulatorpin">
<attribute name="cpuset">
@@ -5693,6 +5712,16 @@
<param name="minInclusive">-1</param>
</data>
</define>
+ <define name="cacheid">
+ <data type="unsignedShort">
+ <param name="pattern">[0-9]+</param>
+ </data>
+ </define>
+ <define name="cachetype">
+ <data type="string">
+ <param name="pattern">(both|code|data)</param>
+ </data>
+ </define>
<!-- weight currently is in range [100, 1000] -->
<define name="weight">
<data type="unsignedInt">
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 0409c62..fa8d03e 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2927,6 +2927,11 @@ void virDomainDefFree(virDomainDefPtr def)
xmlFreeNode(def->metadata);
+ for (i = 0; i < def->cachetune.n_banks; i++)
+ virBitmapFree(def->cachetune.cache_banks[i].vcpus);
+
+ VIR_FREE(def->cachetune.cache_banks);
+
VIR_FREE(def);
}
@@ -16318,6 +16323,81 @@ virDomainVcpuPinDefParseXML(virDomainDefPtr def,
return ret;
}
+/* Parse the XML definition for cachetune
+ * and a cachetune has the form
+ * <cacheId='0' type='both' sizeKib='1024'
vcpus='0,1'/>
+ */
+static int
+virDomainCacheTuneDefParseXML(virDomainDefPtr def,
+ int n,
+ xmlNodePtr* nodes)
+{
+ char* tmp = NULL;
+ size_t i;
+ int type = -1;
+ virDomainCacheBankPtr bank = NULL;
+
+ if (VIR_ALLOC_N(bank, n) < 0)
+ goto cleanup;
+
+ for (i = 0; i < n; i++) {
+ if (!(tmp = virXMLPropString(nodes[i], "cacheId"))) {
+ virReportError(VIR_ERR_XML_ERROR, "%s", _("missing cacheId in
cache tune"));
+ goto cleanup;
+ }
+ if (virStrToLong_uip(tmp, NULL, 10, &(bank[i].cache_id)) < 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("invalid setting for cacheId '%s'"),
tmp);
+ goto cleanup;
+ }
+ VIR_FREE(tmp);
+
+ if (!(tmp = virXMLPropString(nodes[i], "type"))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("missing cache type"));
+ goto cleanup;
+ }
+ if ((type = virCacheTypeFromString(tmp)) < 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("'unsupported cache type '%s'"), tmp);
+ goto cleanup;
+ }
+ VIR_FREE(tmp);
+
+ if (!(tmp = virXMLPropString(nodes[i], "sizeKiB"))) {
+ virReportError(VIR_ERR_XML_ERROR, "%s", _("missing sizeKiB in
cache tune"));
+ goto cleanup;
+ }
+ if (virStrToLong_ull(tmp, NULL, 10, &(bank[i].size)) < 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("invalid setting for cache sizeKiB '%s'"),
tmp);
+ goto cleanup;
+ }
+ /* convert to B */
+ bank[i].size *= 1024;
+ VIR_FREE(tmp);
+
+ if ((tmp = virXMLPropString(nodes[i], "vcpus"))) {
+ if (virBitmapParse(tmp, &bank[i].vcpus, VIR_DOMAIN_CPUMASK_LEN) < 0)
+ goto cleanup;
+
+ if (virBitmapIsAllClear(bank[i].vcpus)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Invalid value of vcpus '%s'"), tmp);
+ goto cleanup;
+ }
+ }
+ }
+
+ def->cachetune.cache_banks = bank;
+ def->cachetune.n_banks = n;
+ return 0;
+
+ cleanup:
+ VIR_FREE(bank);
+ VIR_FREE(tmp);
+ return -1;
+}
/* Parse the XML definition for a iothreadpin
* and an iothreadspin has the form
@@ -17606,6 +17686,14 @@ virDomainDefParseXML(xmlDocPtr xml,
}
VIR_FREE(nodes);
+ if ((n = virXPathNodeSet("./cputune/cachetune", ctxt, &nodes)) < 0)
+ goto error;
+
+ if (n > 0 && virDomainCacheTuneDefParseXML(def, n, nodes) < 0)
+ goto error;
+
+ VIR_FREE(nodes);
+
if ((n = virXPathNodeSet("./cputune/emulatorpin", ctxt, &nodes)) <
0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("cannot extract emulatorpin nodes"));
@@ -17642,7 +17730,6 @@ virDomainDefParseXML(xmlDocPtr xml,
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("cannot extract vcpusched nodes"));
goto error;
- }
for (i = 0; i < n; i++) {
if (virDomainVcpuThreadSchedParse(nodes[i], def) < 0)
@@ -24390,6 +24477,28 @@ virDomainSchedulerFormat(virBufferPtr buf,
}
+static void
+virDomainCacheTuneDefFormat(virBufferPtr buf,
+ virDomainCachetunePtr cache)
+{
+ size_t i;
+
+ for (i = 0; i < cache->n_banks; i ++) {
+ virBufferAsprintf(buf, "<cachetune cacheId='%u' type='%s'
"
+ "sizeKiB='%llu'",
+ cache->cache_banks[i].cache_id,
+ virCacheTypeToString(cache->cache_banks[i].type),
+ cache->cache_banks[i].size / 1024);
+
+ if (cache->cache_banks[i].vcpus)
+ virBufferAsprintf(buf, " vcpus='%s'/>\n",
+ virBitmapFormat(cache->cache_banks[i].vcpus));
+ else
+ virBufferAddLit(buf, "/>\n");
+ }
+}
+
+
static int
virDomainCputuneDefFormat(virBufferPtr buf,
virDomainDefPtr def)
@@ -24436,6 +24545,8 @@ virDomainCputuneDefFormat(virBufferPtr buf,
"</iothread_quota>\n",
def->cputune.iothread_quota);
+ virDomainCacheTuneDefFormat(&childrenBuf, &def->cachetune);
+
for (i = 0; i < def->maxvcpus; i++) {
char *cpumask;
virDomainVcpuDefPtr vcpu = def->vcpus[i];
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 6d9ee97..729b676 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2190,6 +2190,23 @@ struct _virDomainMemtune {
int allocation; /* enum virDomainMemoryAllocation */
};
+typedef struct _virDomainCacheBank virDomainCacheBank;
+typedef virDomainCacheBank *virDomainCacheBankPtr;
+
+struct _virDomainCacheBank {
+ unsigned int cache_id; /* cache id to be allocated on */
+ int type; /* enum virCacheType */
+ unsigned long long size; /* in B */
+ virBitmapPtr vcpus;
+};
+
+typedef struct _virDomainCachetune virDomainCachetune;
+typedef virDomainCachetune *virDomainCachetunePtr;
+struct _virDomainCachetune {
+ size_t n_banks;
+ virDomainCacheBankPtr cache_banks;
+};
+
typedef struct _virDomainPowerManagement virDomainPowerManagement;
typedef virDomainPowerManagement *virDomainPowerManagementPtr;
@@ -2263,6 +2280,8 @@ struct _virDomainDef {
virDomainCputune cputune;
+ virDomainCachetune cachetune;
+
virDomainNumaPtr numa;
virDomainResourceDefPtr resource;
virDomainIdMapDef idmap;
--
1.9.1