mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06: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>
|
<model fallback='allow'>core2duo</model>
|
||||||
<vendor>Intel</vendor>
|
<vendor>Intel</vendor>
|
||||||
<topology sockets='1' cores='2' threads='1'/>
|
<topology sockets='1' cores='2' threads='1'/>
|
||||||
|
<cache level='3' mode='emulate'/>
|
||||||
<feature policy='disable' name='lahf_lm'/>
|
<feature policy='disable' name='lahf_lm'/>
|
||||||
</cpu>
|
</cpu>
|
||||||
...</pre>
|
...</pre>
|
||||||
@ -1211,6 +1212,7 @@
|
|||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
<cpu mode='host-passthrough'>
|
<cpu mode='host-passthrough'>
|
||||||
|
<cache mode='passthrough'/>
|
||||||
<feature policy='disable' name='lahf_lm'/>
|
<feature policy='disable' name='lahf_lm'/>
|
||||||
...</pre>
|
...</pre>
|
||||||
|
|
||||||
@ -1434,6 +1436,39 @@
|
|||||||
<span class="since">Since 0.8.5</span> the <code>policy</code>
|
<span class="since">Since 0.8.5</span> the <code>policy</code>
|
||||||
attribute can be omitted and will default to <code>require</code>.
|
attribute can be omitted and will default to <code>require</code>.
|
||||||
</dd>
|
</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>
|
</dl>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
@ -142,4 +142,25 @@
|
|||||||
</data>
|
</data>
|
||||||
</define>
|
</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>
|
</grammar>
|
||||||
|
@ -4548,6 +4548,9 @@
|
|||||||
<optional>
|
<optional>
|
||||||
<ref name="cpuNuma"/>
|
<ref name="cpuNuma"/>
|
||||||
</optional>
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<ref name="cpuCache"/>
|
||||||
|
</optional>
|
||||||
</interleave>
|
</interleave>
|
||||||
</element>
|
</element>
|
||||||
</define>
|
</define>
|
||||||
|
@ -62,6 +62,12 @@ VIR_ENUM_IMPL(virCPUFeaturePolicy, VIR_CPU_FEATURE_LAST,
|
|||||||
"disable",
|
"disable",
|
||||||
"forbid")
|
"forbid")
|
||||||
|
|
||||||
|
VIR_ENUM_IMPL(virCPUCacheMode, VIR_CPU_CACHE_MODE_LAST,
|
||||||
|
"emulate",
|
||||||
|
"passthrough",
|
||||||
|
"disable")
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
virCPUDefFreeFeatures(virCPUDefPtr def)
|
virCPUDefFreeFeatures(virCPUDefPtr def)
|
||||||
{
|
{
|
||||||
@ -92,6 +98,7 @@ virCPUDefFree(virCPUDefPtr def)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
virCPUDefFreeModel(def);
|
virCPUDefFreeModel(def);
|
||||||
|
VIR_FREE(def->cache);
|
||||||
VIR_FREE(def);
|
VIR_FREE(def);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,7 +211,18 @@ virCPUDefCopyWithoutModel(const virCPUDef *cpu)
|
|||||||
copy->threads = cpu->threads;
|
copy->threads = cpu->threads;
|
||||||
copy->arch = cpu->arch;
|
copy->arch = cpu->arch;
|
||||||
|
|
||||||
|
if (cpu->cache) {
|
||||||
|
if (VIR_ALLOC(copy->cache) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
*copy->cache = *cpu->cache;
|
||||||
|
}
|
||||||
|
|
||||||
return copy;
|
return copy;
|
||||||
|
|
||||||
|
error:
|
||||||
|
virCPUDefFree(copy);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -489,6 +507,41 @@ virCPUDefParseXML(xmlNodePtr node,
|
|||||||
def->features[i].policy = policy;
|
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:
|
cleanup:
|
||||||
ctxt->node = oldnode;
|
ctxt->node = oldnode;
|
||||||
VIR_FREE(fallback);
|
VIR_FREE(fallback);
|
||||||
@ -662,6 +715,15 @@ virCPUDefFormatBuf(virBufferPtr buf,
|
|||||||
virBufferAddLit(buf, "/>\n");
|
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++) {
|
for (i = 0; i < def->nfeatures; i++) {
|
||||||
virCPUFeatureDefPtr feature = def->features + 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 struct _virCPUDef virCPUDef;
|
||||||
typedef virCPUDef *virCPUDefPtr;
|
typedef virCPUDef *virCPUDefPtr;
|
||||||
struct _virCPUDef {
|
struct _virCPUDef {
|
||||||
@ -121,6 +139,7 @@ struct _virCPUDef {
|
|||||||
size_t nfeatures;
|
size_t nfeatures;
|
||||||
size_t nfeatures_max;
|
size_t nfeatures_max;
|
||||||
virCPUFeatureDefPtr features;
|
virCPUFeatureDefPtr features;
|
||||||
|
virCPUCacheDefPtr cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -67,6 +67,8 @@ virCapabilitiesSetNetPrefix;
|
|||||||
|
|
||||||
|
|
||||||
# conf/cpu_conf.h
|
# conf/cpu_conf.h
|
||||||
|
virCPUCacheModeTypeFromString;
|
||||||
|
virCPUCacheModeTypeToString;
|
||||||
virCPUDefAddFeature;
|
virCPUDefAddFeature;
|
||||||
virCPUDefCopy;
|
virCPUDefCopy;
|
||||||
virCPUDefCopyModel;
|
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("vcpus-individual");
|
||||||
|
|
||||||
|
DO_TEST("cpu-cache-emulate");
|
||||||
|
DO_TEST("cpu-cache-passthrough");
|
||||||
|
DO_TEST("cpu-cache-disable");
|
||||||
|
|
||||||
virObjectUnref(caps);
|
virObjectUnref(caps);
|
||||||
virObjectUnref(xmlopt);
|
virObjectUnref(xmlopt);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user