/**
* VIR_PERF_PARAM_CMT:
*
- * Macro for typed parameter name that represents CMT perf event.
+ * Macro for typed parameter name that represents CMT perf event
+ * which can be used to measure the usage of cache (bytes) by
+ * applications running on the platform. It corresponds to the
+ * "perf.cmt" field in the *Stats APIs.
*/
# define VIR_PERF_PARAM_CMT "cmt"
+/**
+ * VIR_PERF_PARAM_MBMT:
+ *
+ * Macro for typed parameter name that represents MBMT perf event
+ * which can be used to monitor total system bandwidth (bytes/s)
+ * from one level of cache to another. It corresponds to the
+ * "perf.mbmt" field in the *Stats APIs.
+
+ */
+# define VIR_PERF_PARAM_MBMT "mbmt"
+
+/**
+ * VIR_PERF_PARAM_MBML:
+ *
+ * Macro for typed parameter name that represents MBML perf event
+ * which can be used to monitor the amount of data (bytes/s) sent
+ * through the memory controller on the socket. It corresponds to
+ * the "perf.mbml" field in the *Stats APIs.
+ */
+# define VIR_PERF_PARAM_MBML "mbml"
+
int virDomainGetPerfEvents(virDomainPtr dom,
virTypedParameterPtr *params,
int *nparams,
* "block.<num>.physical" - physical size in bytes of the container of the
* backing image as unsigned long long.
*
+ * VIR_DOMAIN_STATS_PERF: Return perf event statistics.
+ * The typed parameter keys are in this format:
+ * "perf.cmt" - the usage of l3 cache (bytes) by applications running on the
+ * platform as unsigned long long. It is produced by cmt perf
+ * event.
+ * "perf.mbmt" - the total system bandwidth (bytes/s) from one level of cache
+ * to another as unsigned long long. It is produced by mbmt perf
+ * event.
+ * "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.
+ *
* 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
* applicable for the current state of the guest domain, or their retrieval
if (virTypedParamsValidate(params, nparams,
VIR_PERF_PARAM_CMT, VIR_TYPED_PARAM_BOOLEAN,
+ VIR_PERF_PARAM_MBMT, VIR_TYPED_PARAM_BOOLEAN,
+ VIR_PERF_PARAM_MBML, VIR_TYPED_PARAM_BOOLEAN,
NULL) < 0)
return -1;
#undef QEMU_ADD_COUNT_PARAM
static int
-qemuDomainGetStatsPerfCmt(virPerfPtr perf,
+qemuDomainGetStatsPerfRdt(virPerfPtr perf,
+ virPerfEventType type,
virDomainStatsRecordPtr record,
int *maxparams)
{
- uint64_t cache = 0;
+ char param_name[VIR_TYPED_PARAM_FIELD_LENGTH];
+ uint64_t value = 0;
- if (virPerfReadEvent(perf, VIR_PERF_EVENT_CMT, &cache) < 0)
+ if (virPerfReadEvent(perf, type, &value) < 0)
return -1;
+ snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, "perf.%s",
+ virPerfEventTypeToString(type));
+
if (virTypedParamsAddULLong(&record->params,
&record->nparams,
maxparams,
- "perf.cache",
- cache) < 0)
+ param_name,
+ value) < 0)
return -1;
return 0;
switch (i) {
case VIR_PERF_EVENT_CMT:
- if (qemuDomainGetStatsPerfCmt(priv->perf, record, maxparams) < 0)
+ case VIR_PERF_EVENT_MBMT:
+ case VIR_PERF_EVENT_MBML:
+ if (qemuDomainGetStatsPerfRdt(priv->perf, i, record, maxparams) < 0)
goto cleanup;
break;
}
#define VIR_FROM_THIS VIR_FROM_PERF
VIR_ENUM_IMPL(virPerfEvent, VIR_PERF_EVENT_LAST,
- "cmt");
+ "cmt", "mbmt", "mbml");
struct virPerfEvent {
int type;
}
static int
-virPerfCmtEnable(virPerfEventPtr event,
+virPerfRdtEnable(virPerfEventPtr event,
pid_t pid)
{
- struct perf_event_attr cmt_attr;
+ struct perf_event_attr rdt_attr;
char *buf = NULL;
char *tmp = NULL;
unsigned int event_type, scale;
if (virStrToLong_ui(buf, NULL, 10, &event_type) < 0) {
virReportSystemError(errno, "%s",
- _("failed to get cmt event type"));
+ _("failed to get rdt event type"));
goto error;
}
VIR_FREE(buf);
- if (virFileReadAll("/sys/devices/intel_cqm/events/llc_occupancy.scale",
- 10, &buf) < 0)
- goto error;
+ 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;
- if (virStrToLong_ui(buf, NULL, 10, &scale) < 0) {
- virReportSystemError(errno, "%s",
- _("failed to get cmt scaling factor"));
- goto error;
+ switch (event->type) {
+ case 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) {
+ 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;
}
- event->efields.cmt.scale = scale;
-
- memset(&cmt_attr, 0, sizeof(cmt_attr));
- cmt_attr.size = sizeof(cmt_attr);
- cmt_attr.type = event_type;
- cmt_attr.config = 1;
- cmt_attr.inherit = 1;
- cmt_attr.disabled = 1;
- cmt_attr.enable_on_exec = 0;
-
- event->fd = syscall(__NR_perf_event_open, &cmt_attr, pid, -1, -1, 0);
+ event->fd = syscall(__NR_perf_event_open, &rdt_attr, pid, -1, -1, 0);
if (event->fd < 0) {
virReportSystemError(errno,
_("Unable to open perf type=%d for pid=%d"),
}
if (ioctl(event->fd, PERF_EVENT_IOC_ENABLE) < 0) {
- virReportSystemError(errno, "%s",
- _("Unable to enable perf event for CMT"));
+ virReportSystemError(errno,
+ _("Unable to enable perf event for %s"),
+ virPerfEventTypeToString(event->type));
goto error;
}
switch (type) {
case VIR_PERF_EVENT_CMT:
- if (virPerfCmtEnable(event, pid) < 0)
+ case VIR_PERF_EVENT_MBMT:
+ case VIR_PERF_EVENT_MBML:
+ if (virPerfRdtEnable(event, pid) < 0)
return -1;
break;
case VIR_PERF_EVENT_LAST: