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@xxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list