提交 a646a601 编写于 作者: J Jiri Denemark

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: NJiri Denemark <jdenemar@redhat.com>
上级 e841a411
......@@ -1198,6 +1198,7 @@
&lt;model fallback='allow'&gt;core2duo&lt;/model&gt;
&lt;vendor&gt;Intel&lt;/vendor&gt;
&lt;topology sockets='1' cores='2' threads='1'/&gt;
&lt;cache level='3' mode='emulate'/&gt;
&lt;feature policy='disable' name='lahf_lm'/&gt;
&lt;/cpu&gt;
...</pre>
......@@ -1211,6 +1212,7 @@
<pre>
&lt;cpu mode='host-passthrough'&gt;
&lt;cache mode='passthrough'/&gt;
&lt;feature policy='disable' name='lahf_lm'/&gt;
...</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;
......
<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>
<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>
<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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册