This patch adds new xml element, and so we can have the option of
also having perf events enabled immediately at startup.
Signed-off-by: Qiaowei Ren <qiaowei.ren(a)intel.com>
---
docs/schemas/domaincommon.rng | 27 +++++++++++++++++++++++++++
src/conf/domain_conf.c | 37 +++++++++++++++++++++++++++++++++++++
src/conf/domain_conf.h | 10 ++++++++++
src/qemu/qemu_driver.c | 26 ++++++++++++++++++++++++++
src/qemu/qemu_process.c | 6 ++++--
5 files changed, 104 insertions(+), 2 deletions(-)
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 4804c69..fb4bf2b 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -393,6 +393,33 @@
</define>
<!--
+ Enable or disable perf events for the domain. For each
+ of the events the following rules apply:
+ on: the event will be forcefully enabled
+ off: the event will be forcefully disabled
+ not specified: the event will be disabled by default
+ -->
+ <define name="perf">
+ <element name="perf">
+ <interleave>
+ <optional>
+ <element name="cmt">
+ <ref name="enableChoices"/>
+ </element>
+ </optional>
+ </interleave>
+ <empty/>
+ </element>
+ </define>
+ <define name="enableChoices">
+ <optional>
+ <attribute name="enabled">
+ <ref name="virYesNo"/>
+ </attribute>
+ </optional>
+ </define>
+
+ <!--
The Identifiers can be:
- an optional id attribute with a number on the domain element
- a mandatory name
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 2f5c0ed..833e69f 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -12231,6 +12231,29 @@ virDomainPMStateParseXML(xmlXPathContextPtr ctxt,
static int
+virDomainPerfParseXML(xmlXPathContextPtr ctxt,
+ const char *xpath,
+ int *val)
+{
+ int ret = -1;
+ char *tmp = virXPathString(xpath, ctxt);
+ if (tmp) {
+ *val = virTristateBoolTypeFromString(tmp);
+ if (*val < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unknown perf event state %s"), tmp);
+ goto cleanup;
+ }
+ }
+
+ ret = 0;
+ cleanup:
+ VIR_FREE(tmp);
+ return ret;
+}
+
+
+static int
virDomainMemorySourceDefParseXML(xmlNodePtr node,
xmlXPathContextPtr ctxt,
virDomainMemoryDefPtr def)
@@ -15388,6 +15411,11 @@ virDomainDefParseXML(xmlDocPtr xml,
&def->pm.s4) < 0)
goto error;
+ if (virDomainPerfParseXML(ctxt,
+ "string(./perf/cmt/@enabled)",
+ &def->perf.cmt) < 0)
+ goto error;
+
if ((tmp = virXPathString("string(./clock/@offset)", ctxt)) &&
(def->clock.offset = virDomainClockOffsetTypeFromString(tmp)) < 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@@ -22011,6 +22039,15 @@ virDomainDefFormatInternal(virDomainDefPtr def,
virBufferAddLit(buf, "</pm>\n");
}
+ if (def->perf.cmt) {
+ virBufferAddLit(buf, "<perf>\n");
+ virBufferAdjustIndent(buf, 2);
+ virBufferAsprintf(buf, "<cmt enabled='%s'/>\n",
+ virTristateBoolTypeToString(def->perf.cmt));
+ virBufferAdjustIndent(buf, -2);
+ virBufferAddLit(buf, "</perf>\n");
+ }
+
virBufferAddLit(buf, "<devices>\n");
virBufferAdjustIndent(buf, 2);
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 90d8e13..7383faf 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2192,6 +2192,14 @@ struct _virDomainPowerManagement {
int s4;
};
+typedef struct _virDomainPerf virDomainPerf;
+typedef virDomainPerf *virDomainPerfPtr;
+
+struct _virDomainPerf {
+ /* These options are of type enum virTristateBool */
+ int cmt;
+};
+
typedef struct _virDomainKeyWrapDef virDomainKeyWrapDef;
typedef virDomainKeyWrapDef *virDomainKeyWrapDefPtr;
struct _virDomainKeyWrapDef {
@@ -2242,6 +2250,8 @@ struct _virDomainDef {
virDomainPowerManagement pm;
+ virDomainPerf perf;
+
virDomainOSDef os;
char *emulator;
/* These three options are of type virTristateSwitch,
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 53f5089..7f3c2a5 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -10254,9 +10254,14 @@ qemuDomainSetPerfEvents(virDomainPtr dom,
virTypedParameterPtr params,
int nparams)
{
+ virQEMUDriverPtr driver = dom->conn->privateData;
size_t i;
virDomainObjPtr vm = NULL;
+ virQEMUDriverConfigPtr cfg = NULL;
qemuDomainObjPrivatePtr priv;
+ virDomainDefPtr def;
+ virDomainDefPtr persistentDef;
+ unsigned int flags = VIR_DOMAIN_AFFECT_CURRENT;
int ret = -1;
virPerfEventType type;
bool enabled;
@@ -10267,11 +10272,15 @@ qemuDomainSetPerfEvents(virDomainPtr dom,
if (!(vm = qemuDomObjFromDomain(dom)))
return -1;
+ cfg = virQEMUDriverGetConfig(driver);
priv = vm->privateData;
if (virDomainSetPerfEventsEnsureACL(dom->conn, vm->def) < 0)
goto cleanup;
+ if (virDomainObjGetDefs(vm, flags, &def, &persistentDef) < 0)
+ goto cleanup;
+
for (i = 0; i < nparams; i++) {
virTypedParameterPtr param = ¶ms[i];
enabled = params->value.b;
@@ -10281,12 +10290,29 @@ qemuDomainSetPerfEvents(virDomainPtr dom,
goto cleanup;
if (enabled && virPerfEventEnable(priv->perf, type, vm->pid))
goto cleanup;
+
+ if (def) {
+ def->perf.cmt = enabled ?
+ VIR_TRISTATE_BOOL_YES : VIR_TRISTATE_BOOL_NO;
+
+ if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0)
+ goto cleanup;
+ }
+
+ if (persistentDef) {
+ persistentDef->perf.cmt = enabled ?
+ VIR_TRISTATE_BOOL_YES : VIR_TRISTATE_BOOL_NO;
+
+ if (virDomainSaveConfig(cfg->configDir, persistentDef) < 0)
+ goto cleanup;
+ }
}
ret = 0;
cleanup:
virDomainObjEndAPI(&vm);
+ virObjectUnref(cfg);
return ret;
}
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 0ee8655..45c16ac 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4846,8 +4846,10 @@ qemuProcessLaunch(virConnectPtr conn,
VIR_DEBUG("Initializing perf event");
priv->perf = virPerfNew();
- if (!priv->perf)
- goto cleanup;
+ if (priv->perf) {
+ if (vm->def->perf.cmt == VIR_TRISTATE_BOOL_YES)
+ virPerfEventEnable(priv->perf, VIR_PERF_EVENT_CMT, vm->pid);
+ }
/* This must be done after cgroup placement to avoid resetting CPU
* affinity */
--
1.9.1