mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-19 18:11:31 +00:00
Add support for CPU cache specification
This patch introduces <cache level='N' mode='emulate'/> <cache mode='passthrough'/> <cache mode='disable'/> sub element of /domain/cpu. Currently only a single <cache> element is allowed. Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
This commit is contained in:
parent
e841a41169
commit
a646a6016a
@ -1198,6 +1198,7 @@
|
||||
<model fallback='allow'>core2duo</model>
|
||||
<vendor>Intel</vendor>
|
||||
<topology sockets='1' cores='2' threads='1'/>
|
||||
<cache level='3' mode='emulate'/>
|
||||
<feature policy='disable' name='lahf_lm'/>
|
||||
</cpu>
|
||||
...</pre>
|
||||
@ -1211,6 +1212,7 @@
|
||||
|
||||
<pre>
|
||||
<cpu mode='host-passthrough'>
|
||||
<cache mode='passthrough'/>
|
||||
<feature policy='disable' name='lahf_lm'/>
|
||||
...</pre>
|
||||
|
||||
@ -1434,6 +1436,39 @@
|
||||
<span class="since">Since 0.8.5</span> the <code>policy</code>
|
||||
attribute can be omitted and will default to <code>require</code>.
|
||||
</dd>
|
||||
|
||||
<dt><code>cache</code></dt>
|
||||
<dd><span class="since">Since 3.3.0</span> the <code>cache</code>
|
||||
element describes the virtual CPU cache. If the element is missing,
|
||||
the hypervisor will use a sensible default.
|
||||
|
||||
<dl>
|
||||
<dt><code>level</code></dt>
|
||||
<dd>This optional attribute specifies which cache level is described
|
||||
by the element. Missing attribute means the element describes all
|
||||
CPU cache levels at once. Mixing <code>cache</code> elements with
|
||||
the <code>level</code> attribute set and those without the
|
||||
attribute is forbidden.</dd>
|
||||
|
||||
<dt><code>mode</code></dt>
|
||||
<dd>
|
||||
The following values are supported:
|
||||
<dl>
|
||||
<dt><code>emulate</code></dt>
|
||||
<dd>The hypervisor will provide a fake CPU cache data.</dd>
|
||||
|
||||
<dt><code>passthrough</code></dt>
|
||||
<dd>The real CPU cache data reported by the host CPU will be
|
||||
passed through to the virtual CPU.</dd>
|
||||
|
||||
<dt><code>disable</code></dt>
|
||||
<dd>The virtual CPU will report no CPU cache of the specified
|
||||
level (or no cache at all if the <code>level</code> attribute
|
||||
is missing).</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
|
@ -142,4 +142,25 @@
|
||||
</data>
|
||||
</define>
|
||||
|
||||
<define name="cpuCache">
|
||||
<element name="cache">
|
||||
<optional>
|
||||
<attribute name="level">
|
||||
<choice>
|
||||
<value>1</value>
|
||||
<value>2</value>
|
||||
<value>3</value>
|
||||
</choice>
|
||||
</attribute>
|
||||
</optional>
|
||||
<attribute name="mode">
|
||||
<choice>
|
||||
<value>emulate</value>
|
||||
<value>passthrough</value>
|
||||
<value>disable</value>
|
||||
</choice>
|
||||
</attribute>
|
||||
</element>
|
||||
</define>
|
||||
|
||||
</grammar>
|
||||
|
@ -4548,6 +4548,9 @@
|
||||
<optional>
|
||||
<ref name="cpuNuma"/>
|
||||
</optional>
|
||||
<optional>
|
||||
<ref name="cpuCache"/>
|
||||
</optional>
|
||||
</interleave>
|
||||
</element>
|
||||
</define>
|
||||
|
@ -62,6 +62,12 @@ VIR_ENUM_IMPL(virCPUFeaturePolicy, VIR_CPU_FEATURE_LAST,
|
||||
"disable",
|
||||
"forbid")
|
||||
|
||||
VIR_ENUM_IMPL(virCPUCacheMode, VIR_CPU_CACHE_MODE_LAST,
|
||||
"emulate",
|
||||
"passthrough",
|
||||
"disable")
|
||||
|
||||
|
||||
void
|
||||
virCPUDefFreeFeatures(virCPUDefPtr def)
|
||||
{
|
||||
@ -92,6 +98,7 @@ virCPUDefFree(virCPUDefPtr def)
|
||||
return;
|
||||
|
||||
virCPUDefFreeModel(def);
|
||||
VIR_FREE(def->cache);
|
||||
VIR_FREE(def);
|
||||
}
|
||||
|
||||
@ -204,7 +211,18 @@ virCPUDefCopyWithoutModel(const virCPUDef *cpu)
|
||||
copy->threads = cpu->threads;
|
||||
copy->arch = cpu->arch;
|
||||
|
||||
if (cpu->cache) {
|
||||
if (VIR_ALLOC(copy->cache) < 0)
|
||||
goto error;
|
||||
|
||||
*copy->cache = *cpu->cache;
|
||||
}
|
||||
|
||||
return copy;
|
||||
|
||||
error:
|
||||
virCPUDefFree(copy);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -489,6 +507,41 @@ virCPUDefParseXML(xmlNodePtr node,
|
||||
def->features[i].policy = policy;
|
||||
}
|
||||
|
||||
if (virXPathInt("count(./cache)", ctxt, &n) < 0) {
|
||||
goto cleanup;
|
||||
} else if (n > 1) {
|
||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||
_("at most one CPU cache element may be specified"));
|
||||
goto cleanup;
|
||||
} else if (n == 1) {
|
||||
int level = -1;
|
||||
char *strmode;
|
||||
int mode;
|
||||
|
||||
if (virXPathBoolean("boolean(./cache[1]/@level)", ctxt) == 1 &&
|
||||
(virXPathInt("string(./cache[1]/@level)", ctxt, &level) < 0 ||
|
||||
level < 1 || level > 3)) {
|
||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||
_("invalid CPU cache level, must be in range [1,3]"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!(strmode = virXPathString("string(./cache[1]/@mode)", ctxt)) ||
|
||||
(mode = virCPUCacheModeTypeFromString(strmode)) < 0) {
|
||||
VIR_FREE(strmode);
|
||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||
_("missing or invalid CPU cache mode"));
|
||||
goto cleanup;
|
||||
}
|
||||
VIR_FREE(strmode);
|
||||
|
||||
if (VIR_ALLOC(def->cache) < 0)
|
||||
goto cleanup;
|
||||
|
||||
def->cache->level = level;
|
||||
def->cache->mode = mode;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
ctxt->node = oldnode;
|
||||
VIR_FREE(fallback);
|
||||
@ -662,6 +715,15 @@ virCPUDefFormatBuf(virBufferPtr buf,
|
||||
virBufferAddLit(buf, "/>\n");
|
||||
}
|
||||
|
||||
if (def->cache) {
|
||||
virBufferAddLit(buf, "<cache ");
|
||||
if (def->cache->level != -1)
|
||||
virBufferAsprintf(buf, "level='%d' ", def->cache->level);
|
||||
virBufferAsprintf(buf, "mode='%s'",
|
||||
virCPUCacheModeTypeToString(def->cache->mode));
|
||||
virBufferAddLit(buf, "/>\n");
|
||||
}
|
||||
|
||||
for (i = 0; i < def->nfeatures; i++) {
|
||||
virCPUFeatureDefPtr feature = def->features + i;
|
||||
|
||||
|
@ -103,6 +103,24 @@ struct _virCPUFeatureDef {
|
||||
};
|
||||
|
||||
|
||||
typedef enum {
|
||||
VIR_CPU_CACHE_MODE_EMULATE,
|
||||
VIR_CPU_CACHE_MODE_PASSTHROUGH,
|
||||
VIR_CPU_CACHE_MODE_DISABLE,
|
||||
|
||||
VIR_CPU_CACHE_MODE_LAST
|
||||
} virCPUCacheMode;
|
||||
|
||||
VIR_ENUM_DECL(virCPUCacheMode);
|
||||
|
||||
typedef struct _virCPUCacheDef virCPUCacheDef;
|
||||
typedef virCPUCacheDef *virCPUCacheDefPtr;
|
||||
struct _virCPUCacheDef {
|
||||
int level; /* -1 for unspecified */
|
||||
virCPUCacheMode mode;
|
||||
};
|
||||
|
||||
|
||||
typedef struct _virCPUDef virCPUDef;
|
||||
typedef virCPUDef *virCPUDefPtr;
|
||||
struct _virCPUDef {
|
||||
@ -121,6 +139,7 @@ struct _virCPUDef {
|
||||
size_t nfeatures;
|
||||
size_t nfeatures_max;
|
||||
virCPUFeatureDefPtr features;
|
||||
virCPUCacheDefPtr cache;
|
||||
};
|
||||
|
||||
|
||||
|
@ -67,6 +67,8 @@ virCapabilitiesSetNetPrefix;
|
||||
|
||||
|
||||
# conf/cpu_conf.h
|
||||
virCPUCacheModeTypeFromString;
|
||||
virCPUCacheModeTypeToString;
|
||||
virCPUDefAddFeature;
|
||||
virCPUDefCopy;
|
||||
virCPUDefCopyModel;
|
||||
|
20
tests/genericxml2xmlindata/generic-cpu-cache-disable.xml
Normal file
20
tests/genericxml2xmlindata/generic-cpu-cache-disable.xml
Normal file
@ -0,0 +1,20 @@
|
||||
<domain type='kvm'>
|
||||
<name>foo</name>
|
||||
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
|
||||
<memory unit='KiB'>219136</memory>
|
||||
<currentMemory unit='KiB'>219136</currentMemory>
|
||||
<vcpu placement='static'>1</vcpu>
|
||||
<os>
|
||||
<type arch='i686' machine='pc'>hvm</type>
|
||||
<boot dev='hd'/>
|
||||
</os>
|
||||
<cpu mode='host-passthrough'>
|
||||
<cache mode='disable'/>
|
||||
</cpu>
|
||||
<clock offset='utc'/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>destroy</on_crash>
|
||||
<devices>
|
||||
</devices>
|
||||
</domain>
|
20
tests/genericxml2xmlindata/generic-cpu-cache-emulate.xml
Normal file
20
tests/genericxml2xmlindata/generic-cpu-cache-emulate.xml
Normal file
@ -0,0 +1,20 @@
|
||||
<domain type='kvm'>
|
||||
<name>foo</name>
|
||||
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
|
||||
<memory unit='KiB'>219136</memory>
|
||||
<currentMemory unit='KiB'>219136</currentMemory>
|
||||
<vcpu placement='static'>1</vcpu>
|
||||
<os>
|
||||
<type arch='i686' machine='pc'>hvm</type>
|
||||
<boot dev='hd'/>
|
||||
</os>
|
||||
<cpu mode='host-passthrough'>
|
||||
<cache level='3' mode='emulate'/>
|
||||
</cpu>
|
||||
<clock offset='utc'/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>destroy</on_crash>
|
||||
<devices>
|
||||
</devices>
|
||||
</domain>
|
20
tests/genericxml2xmlindata/generic-cpu-cache-passthrough.xml
Normal file
20
tests/genericxml2xmlindata/generic-cpu-cache-passthrough.xml
Normal file
@ -0,0 +1,20 @@
|
||||
<domain type='kvm'>
|
||||
<name>foo</name>
|
||||
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
|
||||
<memory unit='KiB'>219136</memory>
|
||||
<currentMemory unit='KiB'>219136</currentMemory>
|
||||
<vcpu placement='static'>1</vcpu>
|
||||
<os>
|
||||
<type arch='i686' machine='pc'>hvm</type>
|
||||
<boot dev='hd'/>
|
||||
</os>
|
||||
<cpu mode='host-passthrough'>
|
||||
<cache mode='passthrough'/>
|
||||
</cpu>
|
||||
<clock offset='utc'/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>destroy</on_crash>
|
||||
<devices>
|
||||
</devices>
|
||||
</domain>
|
@ -100,6 +100,10 @@ mymain(void)
|
||||
|
||||
DO_TEST("vcpus-individual");
|
||||
|
||||
DO_TEST("cpu-cache-emulate");
|
||||
DO_TEST("cpu-cache-passthrough");
|
||||
DO_TEST("cpu-cache-disable");
|
||||
|
||||
virObjectUnref(caps);
|
||||
virObjectUnref(xmlopt);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user