aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util')
-rw-r--r--tools/perf/util/evsel.c1
-rw-r--r--tools/perf/util/evsel.h7
-rw-r--r--tools/perf/util/hist.c7
-rw-r--r--tools/perf/util/parse-events.c104
-rw-r--r--tools/perf/util/parse-events.h5
-rw-r--r--tools/perf/util/setup.py2
6 files changed, 104 insertions, 22 deletions
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index c974e08..63cadaf 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -86,6 +86,7 @@ void perf_evsel__delete(struct perf_evsel *evsel)
{
perf_evsel__exit(evsel);
close_cgroup(evsel->cgrp);
+ free(evsel->name);
free(evsel);
}
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 1d3d5a3..f6fc8f6 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -37,6 +37,12 @@ struct perf_sample_id {
struct perf_evsel *evsel;
};
+/** struct perf_evsel - event selector
+ *
+ * @name - Can be set to retain the original event name passed by the user,
+ * so that when showing results in tools such as 'perf stat', we
+ * show the name used, not some alias.
+ */
struct perf_evsel {
struct list_head node;
struct perf_event_attr attr;
@@ -45,6 +51,7 @@ struct perf_evsel {
struct xyarray *id;
struct perf_counts *counts;
int idx;
+ char *name;
void *priv;
struct cgroup_sel *cgrp;
};
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 3f43723..da2899e 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -591,6 +591,7 @@ int hist_entry__snprintf(struct hist_entry *self, char *s, size_t size,
{
struct sort_entry *se;
u64 period, total, period_sys, period_us, period_guest_sys, period_guest_us;
+ u64 nr_events;
const char *sep = symbol_conf.field_sep;
int ret;
@@ -599,6 +600,7 @@ int hist_entry__snprintf(struct hist_entry *self, char *s, size_t size,
if (pair_hists) {
period = self->pair ? self->pair->period : 0;
+ nr_events = self->pair ? self->pair->nr_events : 0;
total = pair_hists->stats.total_period;
period_sys = self->pair ? self->pair->period_sys : 0;
period_us = self->pair ? self->pair->period_us : 0;
@@ -606,6 +608,7 @@ int hist_entry__snprintf(struct hist_entry *self, char *s, size_t size,
period_guest_us = self->pair ? self->pair->period_guest_us : 0;
} else {
period = self->period;
+ nr_events = self->nr_events;
total = session_total;
period_sys = self->period_sys;
period_us = self->period_us;
@@ -646,9 +649,9 @@ int hist_entry__snprintf(struct hist_entry *self, char *s, size_t size,
if (symbol_conf.show_nr_samples) {
if (sep)
- ret += snprintf(s + ret, size - ret, "%c%" PRIu64, *sep, period);
+ ret += snprintf(s + ret, size - ret, "%c%" PRIu64, *sep, nr_events);
else
- ret += snprintf(s + ret, size - ret, "%11" PRIu64, period);
+ ret += snprintf(s + ret, size - ret, "%11" PRIu64, nr_events);
}
if (pair_hists) {
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index cf082da..54a7e26 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -268,6 +268,9 @@ const char *event_name(struct perf_evsel *evsel)
u64 config = evsel->attr.config;
int type = evsel->attr.type;
+ if (evsel->name)
+ return evsel->name;
+
return __event_name(type, config);
}
@@ -782,8 +785,10 @@ int parse_events(const struct option *opt, const char *str, int unset __used)
struct perf_evlist *evlist = *(struct perf_evlist **)opt->value;
struct perf_event_attr attr;
enum event_result ret;
+ const char *ostr;
for (;;) {
+ ostr = str;
memset(&attr, 0, sizeof(attr));
ret = parse_event_symbols(opt, &str, &attr);
if (ret == EVT_FAILED)
@@ -798,6 +803,11 @@ int parse_events(const struct option *opt, const char *str, int unset __used)
if (evsel == NULL)
return -1;
perf_evlist__add(evlist, evsel);
+
+ evsel->name = calloc(str - ostr + 1, 1);
+ if (!evsel->name)
+ return -1;
+ strncpy(evsel->name, ostr, str - ostr);
}
if (*str == 0)
@@ -848,7 +858,7 @@ static const char * const event_type_descriptors[] = {
* Print the events from <debugfs_mount_point>/tracing/events
*/
-static void print_tracepoint_events(void)
+void print_tracepoint_events(const char *subsys_glob, const char *event_glob)
{
DIR *sys_dir, *evt_dir;
struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
@@ -863,6 +873,9 @@ static void print_tracepoint_events(void)
return;
for_each_subsystem(sys_dir, sys_dirent, sys_next) {
+ if (subsys_glob != NULL &&
+ !strglobmatch(sys_dirent.d_name, subsys_glob))
+ continue;
snprintf(dir_path, MAXPATHLEN, "%s/%s", debugfs_path,
sys_dirent.d_name);
@@ -871,6 +884,10 @@ static void print_tracepoint_events(void)
continue;
for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
+ if (event_glob != NULL &&
+ !strglobmatch(evt_dirent.d_name, event_glob))
+ continue;
+
snprintf(evt_path, MAXPATHLEN, "%s:%s",
sys_dirent.d_name, evt_dirent.d_name);
printf(" %-42s [%s]\n", evt_path,
@@ -922,13 +939,61 @@ int is_valid_tracepoint(const char *event_string)
return 0;
}
+void print_events_type(u8 type)
+{
+ struct event_symbol *syms = event_symbols;
+ unsigned int i;
+ char name[64];
+
+ for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) {
+ if (type != syms->type)
+ continue;
+
+ if (strlen(syms->alias))
+ snprintf(name, sizeof(name), "%s OR %s",
+ syms->symbol, syms->alias);
+ else
+ snprintf(name, sizeof(name), "%s", syms->symbol);
+
+ printf(" %-42s [%s]\n", name,
+ event_type_descriptors[type]);
+ }
+}
+
+int print_hwcache_events(const char *event_glob)
+{
+ unsigned int type, op, i, printed = 0;
+
+ for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
+ for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
+ /* skip invalid cache type */
+ if (!is_cache_op_valid(type, op))
+ continue;
+
+ for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
+ char *name = event_cache_name(type, op, i);
+
+ if (event_glob != NULL &&
+ !strglobmatch(name, event_glob))
+ continue;
+
+ printf(" %-42s [%s]\n", name,
+ event_type_descriptors[PERF_TYPE_HW_CACHE]);
+ ++printed;
+ }
+ }
+ }
+
+ return printed;
+}
+
/*
* Print the help text for the event symbols:
*/
-void print_events(void)
+void print_events(const char *event_glob)
{
struct event_symbol *syms = event_symbols;
- unsigned int i, type, op, prev_type = -1;
+ unsigned int i, type, prev_type = -1, printed = 0, ntypes_printed = 0;
char name[40];
printf("\n");
@@ -937,8 +1002,16 @@ void print_events(void)
for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) {
type = syms->type;
- if (type != prev_type)
+ if (type != prev_type && printed) {
printf("\n");
+ printed = 0;
+ ntypes_printed++;
+ }
+
+ if (event_glob != NULL &&
+ !(strglobmatch(syms->symbol, event_glob) ||
+ (syms->alias && strglobmatch(syms->alias, event_glob))))
+ continue;
if (strlen(syms->alias))
sprintf(name, "%s OR %s", syms->symbol, syms->alias);
@@ -948,22 +1021,17 @@ void print_events(void)
event_type_descriptors[type]);
prev_type = type;
+ ++printed;
}
- printf("\n");
- for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
- for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
- /* skip invalid cache type */
- if (!is_cache_op_valid(type, op))
- continue;
-
- for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
- printf(" %-42s [%s]\n",
- event_cache_name(type, op, i),
- event_type_descriptors[PERF_TYPE_HW_CACHE]);
- }
- }
+ if (ntypes_printed) {
+ printed = 0;
+ printf("\n");
}
+ print_hwcache_events(event_glob);
+
+ if (event_glob != NULL)
+ return;
printf("\n");
printf(" %-42s [%s]\n",
@@ -976,7 +1044,7 @@ void print_events(void)
event_type_descriptors[PERF_TYPE_BREAKPOINT]);
printf("\n");
- print_tracepoint_events();
+ print_tracepoint_events(NULL, NULL);
exit(129);
}
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index cf7e94a..212f88e 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -28,7 +28,10 @@ extern int parse_filter(const struct option *opt, const char *str, int unset);
#define EVENTS_HELP_MAX (128*1024)
-extern void print_events(void);
+void print_events(const char *event_glob);
+void print_events_type(u8 type);
+void print_tracepoint_events(const char *subsys_glob, const char *event_glob);
+int print_hwcache_events(const char *event_glob);
extern int is_valid_tracepoint(const char *event_string);
extern char debugfs_path[];
diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py
index 1947b04..e24ffad 100644
--- a/tools/perf/util/setup.py
+++ b/tools/perf/util/setup.py
@@ -5,7 +5,7 @@ from distutils.core import setup, Extension
perf = Extension('perf',
sources = ['util/python.c', 'util/ctype.c', 'util/evlist.c',
'util/evsel.c', 'util/cpumap.c', 'util/thread_map.c',
- 'util/util.c', 'util/xyarray.c'],
+ 'util/util.c', 'util/xyarray.c', 'util/cgroup.c'],
include_dirs = ['util/include'],
extra_compile_args = ['-fno-strict-aliasing', '-Wno-write-strings'])