[libvirt] [PATCH v2 5/8] perf: add new xml element

Qiaowei Ren qiaowei.ren at intel.com
Mon Dec 7 07:53:56 UTC 2015


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 at 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 = &params[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




More information about the libvir-list mailing list