[libvirt] [PATCH v5 0/8] perf: add more perf events support

v4: http://www.redhat.com/archives/libvir-list/2016-July/msg00607.html Reworked/reworded the series slightly. The end result is mostly the same as the original, but with the suggested tweaks. John Ferlan (3): virsh: Add a forward reference to perf command from domstats --perf virsh: Rework the perf event names into a table. util: Move virPerfNew and virPerfFree Qiaowei Ren (5): perf: rename qemuDomainGetStatsPerfRdt() perf: Remove the switch from qemuDomainGetStatsPerf util: Add some comment details for virPerfEventType perf: Adjust the perf initialization perf: add more perf events support docs/formatdomain.html.in | 24 +++ docs/schemas/domaincommon.rng | 4 + include/libvirt/libvirt-domain.h | 39 +++++ src/libvirt-domain.c | 9 ++ src/qemu/qemu_driver.c | 23 ++- src/util/virperf.c | 230 +++++++++++++++++----------- src/util/virperf.h | 14 +- tests/genericxml2xmlindata/generic-perf.xml | 4 + tools/virsh.pod | 40 +++-- 9 files changed, 275 insertions(+), 112 deletions(-) -- 2.7.4

From: Qiaowei Ren <qiaowei.ren@intel.com> This patch rename qemuDomainGetStatsPerfRdt() to qemuDomainGetStatsPerfOneEvent() Signed-off-by: Qiaowei Ren <qiaowei.ren@intel.com> Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/qemu/qemu_driver.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index dbdacba..c45207e 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -19133,10 +19133,10 @@ qemuDomainGetStatsBlock(virQEMUDriverPtr driver, #undef QEMU_ADD_COUNT_PARAM static int -qemuDomainGetStatsPerfRdt(virPerfPtr perf, - virPerfEventType type, - virDomainStatsRecordPtr record, - int *maxparams) +qemuDomainGetStatsPerfOneEvent(virPerfPtr perf, + virPerfEventType type, + virDomainStatsRecordPtr record, + int *maxparams) { char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; uint64_t value = 0; @@ -19176,7 +19176,8 @@ qemuDomainGetStatsPerf(virQEMUDriverPtr driver ATTRIBUTE_UNUSED, case VIR_PERF_EVENT_CMT: case VIR_PERF_EVENT_MBMT: case VIR_PERF_EVENT_MBML: - if (qemuDomainGetStatsPerfRdt(priv->perf, i, record, maxparams) < 0) + if (qemuDomainGetStatsPerfOneEvent(priv->perf, i, record, + maxparams) < 0) goto cleanup; break; } -- 2.7.4

From: Qiaowei Ren <qiaowei.ren@intel.com> Remove the unnecessary switch since all VIR_PERF_EVENT* values are fetched Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/qemu/qemu_driver.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index c45207e..b41eaa3 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -19172,15 +19172,9 @@ qemuDomainGetStatsPerf(virQEMUDriverPtr driver ATTRIBUTE_UNUSED, if (!virPerfEventIsEnabled(priv->perf, i)) continue; - switch (i) { - case VIR_PERF_EVENT_CMT: - case VIR_PERF_EVENT_MBMT: - case VIR_PERF_EVENT_MBML: - if (qemuDomainGetStatsPerfOneEvent(priv->perf, i, record, - maxparams) < 0) - goto cleanup; - break; - } + if (qemuDomainGetStatsPerfOneEvent(priv->perf, i, + record, maxparams) < 0) + goto cleanup; } ret = 0; -- 2.7.4

From: Qiaowei Ren <qiaowei.ren@intel.com> Add to some details for the existing enum Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/util/virperf.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/util/virperf.h b/src/util/virperf.h index 7163410..bdafe03 100644 --- a/src/util/virperf.h +++ b/src/util/virperf.h @@ -24,10 +24,13 @@ # include "virutil.h" +/* Some Intel processor families introduced some RDT (Resource Director + * Technology) features to monitor or control shared resource based on + * the perf framework in the linux kernel. */ typedef enum { - VIR_PERF_EVENT_CMT, - VIR_PERF_EVENT_MBMT, - VIR_PERF_EVENT_MBML, + VIR_PERF_EVENT_CMT, /* Cache Monitoring Technology */ + VIR_PERF_EVENT_MBMT, /* Memory Bandwidth Monitoring Total */ + VIR_PERF_EVENT_MBML, /* Memory Bandwidth Monitor Limit for controller */ VIR_PERF_EVENT_LAST } virPerfEventType; -- 2.7.4

Keep the details in one place... Signed-off-by: John Ferlan <jferlan@redhat.com> --- tools/virsh.pod | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/virsh.pod b/tools/virsh.pod index 97d16c5..00b5d51 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -935,6 +935,8 @@ I<--perf> returns the statistics of all enabled perf events: "perf.mbmt" - total system bandwidth from one level of cache "perf.mbml" - bandwidth of memory traffic for a memory controller +See the B<perf> command for more details about each event. + I<--block> returns information about disks associated with each domain. Using the I<--backing> flag extends this information to cover all resources in the backing chain, rather than the default -- 2.7.4

Should be easier to read Signed-off-by: John Ferlan <jferlan@redhat.com> --- tools/virsh.pod | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/tools/virsh.pod b/tools/virsh.pod index 00b5d51..7ce498b 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -2225,16 +2225,21 @@ from different sources can be supported by perf. Currently only QEMU/KVM supports this command. The I<--enable> and I<--disable> option combined with B<eventSpec> can be used to enabled or disable specific performance event. B<eventSpec> is a string list of one or more events -separated by commas. Valid event names are "cmt", "mbmt", "mbml". -CMT is a PQos (Platform Qos) feature to monitor the usage of cache by -applications running on the platform. -MBM (Memory Bandwidth Monitoring) provides a way to monitor the Total -system memory bandwidth between one level of cache and another (mbmt) -and the amount of data (bytes/s) sent through the memory controller on -the socket (mbml). - -The statistics can be retrieved using the B<domstats> command using the -I<--perf> flag. +separated by commas. Valid event names are as follows: + +B<Valid perf event names> + cmt - A PQos (Platform Qos) feature to monitor the + usage of cache by applications running on the + platform. + mbmt - Provides a way to monitor the total system + memory bandwidth between one level of cache + and another. + mbml - Provides a way to limit the amount of data + (bytes/s) send through the memory controller + on the socket. + +B<Note>: The statistics can be retrieved using the B<domstats> command using +the I<--perf> flag. If I<--live> is specified, affect a running guest. If I<--config> is specified, affect the next boot of a persistent guest. -- 2.7.4

Move them to the bottom under the #ifdef code. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/util/virperf.c | 68 +++++++++++++++++++++++++++--------------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/src/util/virperf.c b/src/util/virperf.c index 4661ba3..627b2ec 100644 --- a/src/util/virperf.c +++ b/src/util/virperf.c @@ -57,40 +57,6 @@ struct virPerf { struct virPerfEvent events[VIR_PERF_EVENT_LAST]; }; -virPerfPtr -virPerfNew(void) -{ - size_t i; - virPerfPtr perf; - - if (VIR_ALLOC(perf) < 0) - return NULL; - - for (i = 0; i < VIR_PERF_EVENT_LAST; i++) { - perf->events[i].type = i; - perf->events[i].fd = -1; - perf->events[i].enabled = false; - } - - return perf; -} - -void -virPerfFree(virPerfPtr perf) -{ - size_t i; - - if (perf == NULL) - return; - - for (i = 0; i < VIR_PERF_EVENT_LAST; i++) { - if (perf->events[i].enabled) - virPerfEventDisable(perf, i); - } - - VIR_FREE(perf); -} - #if defined(__linux__) && defined(HAVE_SYS_SYSCALL_H) # include <linux/perf_event.h> @@ -303,3 +269,37 @@ virPerfReadEvent(virPerfPtr perf ATTRIBUTE_UNUSED, } #endif + +virPerfPtr +virPerfNew(void) +{ + size_t i; + virPerfPtr perf; + + if (VIR_ALLOC(perf) < 0) + return NULL; + + for (i = 0; i < VIR_PERF_EVENT_LAST; i++) { + perf->events[i].type = i; + perf->events[i].fd = -1; + perf->events[i].enabled = false; + } + + return perf; +} + +void +virPerfFree(virPerfPtr perf) +{ + size_t i; + + if (perf == NULL) + return; + + for (i = 0; i < VIR_PERF_EVENT_LAST; i++) { + if (perf->events[i].enabled) + virPerfEventDisable(perf, i); + } + + VIR_FREE(perf); +} -- 2.7.4

From: Qiaowei Ren <qiaowei.ren@intel.com> Introduce a static attr table and refactor virPerfEventEnable() for general purpose usage. This patch creates a static table/matrix that converts the VIR_PERF_EVENT_* events into their respective "attr.type" and "attr.config" so that virPerfEventEnable doesn't have the switch the calling function passes by value the 'type'. Signed-off-by: Qiaowei Ren <qiaowei.ren@intel.com> Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/util/virperf.c | 164 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 103 insertions(+), 61 deletions(-) diff --git a/src/util/virperf.c b/src/util/virperf.c index 627b2ec..018000a 100644 --- a/src/util/virperf.c +++ b/src/util/virperf.c @@ -61,13 +61,24 @@ struct virPerf { # include <linux/perf_event.h> -static virPerfEventPtr -virPerfGetEvent(virPerfPtr perf, - virPerfEventType type) -{ - if (!perf) - return NULL; +struct virPerfEventAttr { + int type; + unsigned int attrType; + unsigned long long attrConfig; +}; + +static struct virPerfEventAttr attrs[] = { + {.type = VIR_PERF_EVENT_CMT, .attrType = 0, .attrConfig = 1}, + {.type = VIR_PERF_EVENT_MBMT, .attrType = 0, .attrConfig = 2}, + {.type = VIR_PERF_EVENT_MBML, .attrType = 0, .attrConfig = 3}, +}; +typedef struct virPerfEventAttr *virPerfEventAttrPtr; + +static virPerfEventAttrPtr +virPerfGetEventAttr(virPerfEventType type) +{ + size_t i; if (type >= VIR_PERF_EVENT_LAST) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Event '%d' is not supported"), @@ -75,67 +86,113 @@ virPerfGetEvent(virPerfPtr perf, return NULL; } - return perf->events + type; + for (i = 0; i < VIR_PERF_EVENT_LAST; i++) { + if (i == type) + return attrs + i; + } + + return NULL; } + static int -virPerfRdtEnable(virPerfEventPtr event, - pid_t pid) +virPerfRdtAttrInit(void) { - struct perf_event_attr rdt_attr; char *buf = NULL; char *tmp = NULL; - unsigned int event_type, scale; + unsigned int attr_type = 0; - if (virFileReadAll("/sys/devices/intel_cqm/type", - 10, &buf) < 0) + if (virFileReadAll("/sys/devices/intel_cqm/type", 10, &buf) < 0) goto error; if ((tmp = strchr(buf, '\n'))) *tmp = '\0'; - if (virStrToLong_ui(buf, NULL, 10, &event_type) < 0) { + if (virStrToLong_ui(buf, NULL, 10, &attr_type) < 0) { virReportSystemError(errno, "%s", _("failed to get rdt event type")); goto error; } VIR_FREE(buf); - memset(&rdt_attr, 0, sizeof(rdt_attr)); - rdt_attr.size = sizeof(rdt_attr); - rdt_attr.type = event_type; - rdt_attr.inherit = 1; - rdt_attr.disabled = 1; - rdt_attr.enable_on_exec = 0; + attrs[VIR_PERF_EVENT_CMT].attrType = attr_type; + attrs[VIR_PERF_EVENT_MBMT].attrType = attr_type; + attrs[VIR_PERF_EVENT_MBML].attrType = attr_type; + + return 0; + + error: + VIR_FREE(buf); + return -1; +} + + +static virPerfEventPtr +virPerfGetEvent(virPerfPtr perf, + virPerfEventType type) +{ + if (!perf) + return NULL; + + if (type >= VIR_PERF_EVENT_LAST) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Event '%d' is not supported"), + type); + return NULL; + } + + return perf->events + type; +} + +int +virPerfEventEnable(virPerfPtr perf, + virPerfEventType type, + pid_t pid) +{ + char *buf = NULL; + struct perf_event_attr attr; + virPerfEventPtr event = virPerfGetEvent(perf, type); + virPerfEventAttrPtr event_attr = virPerfGetEventAttr(type); + + if (!event || !event_attr) + return -1; - switch (event->type) { - case VIR_PERF_EVENT_CMT: + if (event_attr->attrType == 0 && (type == VIR_PERF_EVENT_CMT || + type == VIR_PERF_EVENT_MBMT || + type == VIR_PERF_EVENT_MBML)) { + virReportSystemError(errno, + _("Unable to open perf event for %s"), + virPerfEventTypeToString(event->type)); + return -1; + } + + if (type == VIR_PERF_EVENT_CMT) { if (virFileReadAll("/sys/devices/intel_cqm/events/llc_occupancy.scale", 10, &buf) < 0) goto error; - if (virStrToLong_ui(buf, NULL, 10, &scale) < 0) { + if (virStrToLong_i(buf, NULL, 10, &event->efields.cmt.scale) < 0) { virReportSystemError(errno, "%s", _("failed to get cmt scaling factor")); goto error; } - event->efields.cmt.scale = scale; - - rdt_attr.config = 1; - break; - case VIR_PERF_EVENT_MBMT: - rdt_attr.config = 2; - break; - case VIR_PERF_EVENT_MBML: - rdt_attr.config = 3; - break; + + VIR_FREE(buf); } - event->fd = syscall(__NR_perf_event_open, &rdt_attr, pid, -1, -1, 0); + memset(&attr, 0, sizeof(attr)); + attr.size = sizeof(attr); + attr.inherit = 1; + attr.disabled = 1; + attr.enable_on_exec = 0; + attr.type = event_attr->attrType; + attr.config = event_attr->attrConfig; + + event->fd = syscall(__NR_perf_event_open, &attr, pid, -1, -1, 0); if (event->fd < 0) { virReportSystemError(errno, - _("Unable to open perf type=%d for pid=%d"), - event_type, pid); + _("Unable to open perf event for %s"), + virPerfEventTypeToString(event->type)); goto error; } @@ -156,31 +213,6 @@ virPerfRdtEnable(virPerfEventPtr event, } int -virPerfEventEnable(virPerfPtr perf, - virPerfEventType type, - pid_t pid) -{ - virPerfEventPtr event = virPerfGetEvent(perf, type); - if (event == NULL) - return -1; - - switch (type) { - case VIR_PERF_EVENT_CMT: - case VIR_PERF_EVENT_MBMT: - case VIR_PERF_EVENT_MBML: - if (virPerfRdtEnable(event, pid) < 0) - return -1; - break; - case VIR_PERF_EVENT_LAST: - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Unexpected perf event type=%d"), type); - return -1; - } - - return 0; -} - -int virPerfEventDisable(virPerfPtr perf, virPerfEventType type) { @@ -232,6 +264,13 @@ virPerfReadEvent(virPerfPtr perf, } #else +static int +virPerfRdtAttrInit(void) +{ + return 0; +} + + int virPerfEventEnable(virPerfPtr perf ATTRIBUTE_UNUSED, virPerfEventType type ATTRIBUTE_UNUSED, @@ -285,6 +324,9 @@ virPerfNew(void) perf->events[i].enabled = false; } + if (virPerfRdtAttrInit() < 0) + virResetLastError(); + return perf; } -- 2.7.4

From: Qiaowei Ren <qiaowei.ren@intel.com> With current perf framework, this patch adds support and documentation for more perf events, including cache misses, cache references, cpu cycles, and instructions. Signed-off-by: Qiaowei Ren <qiaowei.ren@intel.com> Signed-off-by: John Ferlan <jferlan@redhat.com> --- docs/formatdomain.html.in | 24 ++++++++++++++++++ docs/schemas/domaincommon.rng | 4 +++ include/libvirt/libvirt-domain.h | 39 +++++++++++++++++++++++++++++ src/libvirt-domain.c | 9 +++++++ src/qemu/qemu_driver.c | 4 +++ src/util/virperf.c | 16 +++++++++++- src/util/virperf.h | 5 ++++ tests/genericxml2xmlindata/generic-perf.xml | 4 +++ tools/virsh.pod | 13 ++++++++++ 9 files changed, 117 insertions(+), 1 deletion(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index fa88839..f7c5d3b 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -1867,6 +1867,10 @@ <event name='cmt' enabled='yes'/> <event name='mbmt' enabled='no'/> <event name='mbml' enabled='yes'/> + <event name='cpu_cycles' enabled='no'/> + <event name='instructions' enabled='yes'/> + <event name='cache_references' enabled='no'/> + <event name='cache_misses' enabled='no'/> </perf> ... </pre> @@ -1892,6 +1896,26 @@ <td>bandwidth of memory traffic for a memory controller</td> <td><code>perf.mbml</code></td> </tr> + <tr> + <td><code>cpu_cycles</code></td> + <td>the number of cpu cycles one instruction needs</td> + <td><code>perf.cpu_cycles</code></td> + </tr> + <tr> + <td><code>instructions</code></td> + <td>the count of instructions by applications running on the platform</td> + <td><code>perf.instructions</code></td> + </tr> + <tr> + <td><code>cache_references</code></td> + <td>the count of cache hits by applications running on the platform</td> + <td><code>perf.cache_references</code></td> + </tr> + <tr> + <td><code>cache_misses</code></td> + <td>the count of cache misses by applications running on the platform</td> + <td><code>perf.cache_misses</code></td> + </tr> </table> <h3><a name="elementsDevices">Devices</a></h3> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index cb9f134..715ccc5 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -414,6 +414,10 @@ <value>cmt</value> <value>mbmt</value> <value>mbml</value> + <value>cpu_cycles</value> + <value>instructions</value> + <value>cache_references</value> + <value>cache_misses</value> </choice> </attribute> <attribute name="enabled"> diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index 42a2bea..6e0e7fb 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -1972,6 +1972,45 @@ void virDomainStatsRecordListFree(virDomainStatsRecordPtr *stats); */ # define VIR_PERF_PARAM_MBML "mbml" +/** + * VIR_PERF_PARAM_CACHE_MISSES: + * + * Macro for typed parameter name that represents cache_misses perf + * event which can be used to measure the count of cache misses by + * applications running on the platform. It corresponds to the + * "perf.cache_misses" field in the *Stats APIs. + */ +# define VIR_PERF_PARAM_CACHE_MISSES "cache_misses" + +/** + * VIR_PERF_PARAM_CACHE_REFERENCES: + * + * Macro for typed parameter name that represents cache_references + * perf event which can be used to measure the count of cache hits + * by applications running on the platform. It corresponds to the + * "perf.cache_references" field in the *Stats APIs. + */ +# define VIR_PERF_PARAM_CACHE_REFERENCES "cache_references" + +/** + * VIR_PERF_PARAM_INSTRUCTIONS: + * + * Macro for typed parameter name that represents instructions perf + * event which can be used to measure the count of instructions + * by applications running on the platform. It corresponds to the + * "perf.instructions" field in the *Stats APIs. + */ +# define VIR_PERF_PARAM_INSTRUCTIONS "instructions" + +/** + * VIR_PERF_PARAM_CPU_CYCLES: + * + * Macro for typed parameter name that represents cpu_cycles perf event + * which can be used to measure how many cpu cycles one instruction needs. + * It corresponds to the "perf.cpu_cycles" field in the *Stats APIs. + */ +# define VIR_PERF_PARAM_CPU_CYCLES "cpu_cycles" + int virDomainGetPerfEvents(virDomainPtr dom, virTypedParameterPtr *params, int *nparams, diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index 4f08349..46f0318 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -11457,6 +11457,15 @@ virConnectGetDomainCapabilities(virConnectPtr conn, * "perf.mbml" - the amount of data (bytes/s) sent through the memory controller * on the socket as unsigned long long. It is produced by mbml * perf event. + * "perf.cache_misses" - the count of cache misses as unsigned long long. + * It is produced by cache_misses perf event. + * "perf.cache_references" - the count of cache hits as unsigned long long. + * It is produced by cache_references perf event. + * "perf.instructions" - The count of instructions as unsigned long long. + * It is produced by instructions perf event. + * "perf.cpu_cycles" - The number of cpu cycles one instruction needs as + * unsigned long long. It is produced by cpu_cycles + * perf event. * * Note that entire stats groups or individual stat fields may be missing from * the output in case they are not supported by the given hypervisor, are not diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index b41eaa3..b81745d 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -9637,6 +9637,10 @@ qemuDomainSetPerfEvents(virDomainPtr dom, VIR_PERF_PARAM_CMT, VIR_TYPED_PARAM_BOOLEAN, VIR_PERF_PARAM_MBMT, VIR_TYPED_PARAM_BOOLEAN, VIR_PERF_PARAM_MBML, VIR_TYPED_PARAM_BOOLEAN, + VIR_PERF_PARAM_CPU_CYCLES, VIR_TYPED_PARAM_BOOLEAN, + VIR_PERF_PARAM_INSTRUCTIONS, VIR_TYPED_PARAM_BOOLEAN, + VIR_PERF_PARAM_CACHE_REFERENCES, VIR_TYPED_PARAM_BOOLEAN, + VIR_PERF_PARAM_CACHE_MISSES, VIR_TYPED_PARAM_BOOLEAN, NULL) < 0) return -1; diff --git a/src/util/virperf.c b/src/util/virperf.c index 018000a..cd66b05 100644 --- a/src/util/virperf.c +++ b/src/util/virperf.c @@ -38,7 +38,9 @@ VIR_LOG_INIT("util.perf"); #define VIR_FROM_THIS VIR_FROM_PERF VIR_ENUM_IMPL(virPerfEvent, VIR_PERF_EVENT_LAST, - "cmt", "mbmt", "mbml"); + "cmt", "mbmt", "mbml", + "cpu_cycles", "instructions", + "cache_references", "cache_misses"); struct virPerfEvent { int type; @@ -71,6 +73,18 @@ static struct virPerfEventAttr attrs[] = { {.type = VIR_PERF_EVENT_CMT, .attrType = 0, .attrConfig = 1}, {.type = VIR_PERF_EVENT_MBMT, .attrType = 0, .attrConfig = 2}, {.type = VIR_PERF_EVENT_MBML, .attrType = 0, .attrConfig = 3}, + {.type = VIR_PERF_EVENT_CPU_CYCLES, + .attrType = PERF_TYPE_HARDWARE, + .attrConfig = PERF_COUNT_HW_CPU_CYCLES}, + {.type = VIR_PERF_EVENT_INSTRUCTIONS, + .attrType = PERF_TYPE_HARDWARE, + .attrConfig = PERF_COUNT_HW_INSTRUCTIONS}, + {.type = VIR_PERF_EVENT_CACHE_REFERENCES, + .attrType = PERF_TYPE_HARDWARE, + .attrConfig = PERF_COUNT_HW_CACHE_REFERENCES}, + {.type = VIR_PERF_EVENT_CACHE_MISSES, + .attrType = PERF_TYPE_HARDWARE, + .attrConfig = PERF_COUNT_HW_CACHE_MISSES}, }; typedef struct virPerfEventAttr *virPerfEventAttrPtr; diff --git a/src/util/virperf.h b/src/util/virperf.h index bdafe03..41be878 100644 --- a/src/util/virperf.h +++ b/src/util/virperf.h @@ -32,6 +32,11 @@ typedef enum { VIR_PERF_EVENT_MBMT, /* Memory Bandwidth Monitoring Total */ VIR_PERF_EVENT_MBML, /* Memory Bandwidth Monitor Limit for controller */ + VIR_PERF_EVENT_CPU_CYCLES, /* CPU Cycles per instruction */ + VIR_PERF_EVENT_INSTRUCTIONS, /* Count of instructions for application */ + VIR_PERF_EVENT_CACHE_REFERENCES, /* Cache hits by applications */ + VIR_PERF_EVENT_CACHE_MISSES, /* Cache misses by applications */ + VIR_PERF_EVENT_LAST } virPerfEventType; diff --git a/tests/genericxml2xmlindata/generic-perf.xml b/tests/genericxml2xmlindata/generic-perf.xml index 394d2a6..a914133 100644 --- a/tests/genericxml2xmlindata/generic-perf.xml +++ b/tests/genericxml2xmlindata/generic-perf.xml @@ -16,6 +16,10 @@ <event name='cmt' enabled='yes'/> <event name='mbmt' enabled='no'/> <event name='mbml' enabled='yes'/> + <event name='cpu_cycles' enabled='no'/> + <event name='instructions' enabled='yes'/> + <event name='cache_references' enabled='no'/> + <event name='cache_misses' enabled='no'/> </perf> <devices> </devices> diff --git a/tools/virsh.pod b/tools/virsh.pod index 7ce498b..0a77978 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -934,6 +934,10 @@ I<--perf> returns the statistics of all enabled perf events: "perf.cmt" - the cache usage in Byte currently used "perf.mbmt" - total system bandwidth from one level of cache "perf.mbml" - bandwidth of memory traffic for a memory controller +"perf.cpu_cycles" - the number of cpu cycles one instruction needs +"perf.instructions" - the count of instructions +"perf.cache_references" - the count of cache hits +"perf.cache_misses" - the count of caches misses See the B<perf> command for more details about each event. @@ -2237,6 +2241,15 @@ B<Valid perf event names> mbml - Provides a way to limit the amount of data (bytes/s) send through the memory controller on the socket. + cache_misses - Provides the count of cache misses by + applications running on the platform. + cache_references - Provides the count of cache hits by + applications running on th e platform. + instructions - Provides the count of instructions executed + by applications running on the platform. + cpu_cycles - Provides the number of cpu_cycles for one + instruction. May be used with instructions + in order to get a cycles per instruction. B<Note>: The statistics can be retrieved using the B<domstats> command using the I<--perf> flag. -- 2.7.4

Hi John, How about this patch series? Thanks, Qiaowei
-----Original Message----- From: John Ferlan [mailto:jferlan@redhat.com] Sent: Thursday, August 4, 2016 6:31 AM To: libvir-list@redhat.com Cc: Ren, Qiaowei <qiaowei.ren@intel.com> Subject: [PATCH v5 0/8] perf: add more perf events support
v4: http://www.redhat.com/archives/libvir-list/2016-July/msg00607.html
Reworked/reworded the series slightly. The end result is mostly the same as the original, but with the suggested tweaks.
John Ferlan (3): virsh: Add a forward reference to perf command from domstats --perf virsh: Rework the perf event names into a table. util: Move virPerfNew and virPerfFree
Qiaowei Ren (5): perf: rename qemuDomainGetStatsPerfRdt() perf: Remove the switch from qemuDomainGetStatsPerf util: Add some comment details for virPerfEventType perf: Adjust the perf initialization perf: add more perf events support
docs/formatdomain.html.in | 24 +++ docs/schemas/domaincommon.rng | 4 + include/libvirt/libvirt-domain.h | 39 +++++ src/libvirt-domain.c | 9 ++ src/qemu/qemu_driver.c | 23 ++- src/util/virperf.c | 230 +++++++++++++++++----------- src/util/virperf.h | 14 +- tests/genericxml2xmlindata/generic-perf.xml | 4 + tools/virsh.pod | 40 +++-- 9 files changed, 275 insertions(+), 112 deletions(-)
-- 2.7.4

On 08/29/2016 10:00 PM, Ren, Qiaowei wrote:
Hi John,
How about this patch series?
I made adjustments to your series, but I also made tweaks and those needed to be OK'd/checked by someone such as you.... Go back to the v4 series and read my comment. In particular from review of patch 2 and more specifically code flow changes w/r/t the initialization which now mostly become patch 7. So please go through the series, make sure it "works" as you expect and let me know. Once that's done and 2.2 is released, I can push these. If tweaks need to be made, then we can do so.
Thanks, Qiaowei
-----Original Message----- From: John Ferlan [mailto:jferlan@redhat.com] Sent: Thursday, August 4, 2016 6:31 AM To: libvir-list@redhat.com Cc: Ren, Qiaowei <qiaowei.ren@intel.com> Subject: [PATCH v5 0/8] perf: add more perf events support
v4: http://www.redhat.com/archives/libvir-list/2016-July/msg00607.html
Reworked/reworded the series slightly. The end result is mostly the same as the original, but with the suggested tweaks.
John Ferlan (3): virsh: Add a forward reference to perf command from domstats --perf virsh: Rework the perf event names into a table. util: Move virPerfNew and virPerfFree
Qiaowei Ren (5): perf: rename qemuDomainGetStatsPerfRdt() perf: Remove the switch from qemuDomainGetStatsPerf util: Add some comment details for virPerfEventType perf: Adjust the perf initialization perf: add more perf events support
docs/formatdomain.html.in | 24 +++ docs/schemas/domaincommon.rng | 4 + include/libvirt/libvirt-domain.h | 39 +++++ src/libvirt-domain.c | 9 ++ src/qemu/qemu_driver.c | 23 ++- src/util/virperf.c | 230 +++++++++++++++++----------- src/util/virperf.h | 14 +- tests/genericxml2xmlindata/generic-perf.xml | 4 + tools/virsh.pod | 40 +++-- 9 files changed, 275 insertions(+), 112 deletions(-)
-- 2.7.4

-----Original Message----- From: John Ferlan [mailto:jferlan@redhat.com] Sent: Tuesday, August 30, 2016 7:40 PM To: Ren, Qiaowei <qiaowei.ren@intel.com>; libvir-list@redhat.com Subject: Re: [PATCH v5 0/8] perf: add more perf events support
On 08/29/2016 10:00 PM, Ren, Qiaowei wrote:
Hi John,
How about this patch series?
I made adjustments to your series, but I also made tweaks and those needed to be OK'd/checked by someone such as you.... Go back to the v4 series and read my comment. In particular from review of patch 2 and more specifically code flow changes w/r/t the initialization which now mostly become patch 7.
So please go through the series, make sure it "works" as you expect and let me know. Once that's done and 2.2 is released, I can push these. If tweaks need to be made, then we can do so.
John, I just checked and did some testing for new series, and it could work. So if no more comments, I guess that you can push these. Thanks for your feedback. - Qiaowei
participants (2)
-
John Ferlan
-
Ren, Qiaowei