diff options
author | Andi Kleen <ak@linux.intel.com> | 2013-04-20 14:02:29 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2013-07-12 12:53:53 -0400 |
commit | dc098b35b56f83ae088e4291a4e389a6ff126965 (patch) | |
tree | 485b4a870edc5b4bfeada71859c271cf1d9742cf /tools/perf | |
parent | 50e200f07948400694238e08e7add73df5ba8f83 (diff) |
perf list: List kernel supplied event aliases
List the kernel supplied pmu event aliases in perf list
It's better when the users can actually see them.
Signed-off-by: Andi Kleen <ak@linux.intel.com>
Link: http://lkml.kernel.org/r/1366480949-32292-2-git-send-email-andi@firstfloor.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r-- | tools/perf/Documentation/perf-list.txt | 4 | ||||
-rw-r--r-- | tools/perf/builtin-list.c | 3 | ||||
-rw-r--r-- | tools/perf/util/parse-events.c | 5 | ||||
-rw-r--r-- | tools/perf/util/pmu.c | 73 | ||||
-rw-r--r-- | tools/perf/util/pmu.h | 3 |
5 files changed, 86 insertions, 2 deletions
diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt index d1e39dc8c810..826f3d6d1d28 100644 --- a/tools/perf/Documentation/perf-list.txt +++ b/tools/perf/Documentation/perf-list.txt | |||
@@ -8,7 +8,7 @@ perf-list - List all symbolic event types | |||
8 | SYNOPSIS | 8 | SYNOPSIS |
9 | -------- | 9 | -------- |
10 | [verse] | 10 | [verse] |
11 | 'perf list' [hw|sw|cache|tracepoint|event_glob] | 11 | 'perf list' [hw|sw|cache|tracepoint|pmu|event_glob] |
12 | 12 | ||
13 | DESCRIPTION | 13 | DESCRIPTION |
14 | ----------- | 14 | ----------- |
@@ -104,6 +104,8 @@ To limit the list use: | |||
104 | 'subsys_glob:event_glob' to filter by tracepoint subsystems such as sched, | 104 | 'subsys_glob:event_glob' to filter by tracepoint subsystems such as sched, |
105 | block, etc. | 105 | block, etc. |
106 | 106 | ||
107 | . 'pmu' to print the kernel supplied PMU events. | ||
108 | |||
107 | . If none of the above is matched, it will apply the supplied glob to all | 109 | . If none of the above is matched, it will apply the supplied glob to all |
108 | events, printing the ones that match. | 110 | events, printing the ones that match. |
109 | 111 | ||
diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index 1948eceb517a..e79f423cc302 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include "util/parse-events.h" | 14 | #include "util/parse-events.h" |
15 | #include "util/cache.h" | 15 | #include "util/cache.h" |
16 | #include "util/pmu.h" | ||
16 | 17 | ||
17 | int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused) | 18 | int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused) |
18 | { | 19 | { |
@@ -37,6 +38,8 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused) | |||
37 | else if (strcmp(argv[i], "cache") == 0 || | 38 | else if (strcmp(argv[i], "cache") == 0 || |
38 | strcmp(argv[i], "hwcache") == 0) | 39 | strcmp(argv[i], "hwcache") == 0) |
39 | print_hwcache_events(NULL, false); | 40 | print_hwcache_events(NULL, false); |
41 | else if (strcmp(argv[i], "pmu") == 0) | ||
42 | print_pmu_events(NULL, false); | ||
40 | else if (strcmp(argv[i], "--raw-dump") == 0) | 43 | else if (strcmp(argv[i], "--raw-dump") == 0) |
41 | print_events(NULL, true); | 44 | print_events(NULL, true); |
42 | else { | 45 | else { |
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index a5076f4f6016..2c460ede0a69 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
@@ -1110,6 +1110,8 @@ int print_hwcache_events(const char *event_glob, bool name_only) | |||
1110 | } | 1110 | } |
1111 | } | 1111 | } |
1112 | 1112 | ||
1113 | if (printed) | ||
1114 | printf("\n"); | ||
1113 | return printed; | 1115 | return printed; |
1114 | } | 1116 | } |
1115 | 1117 | ||
@@ -1164,11 +1166,12 @@ void print_events(const char *event_glob, bool name_only) | |||
1164 | 1166 | ||
1165 | print_hwcache_events(event_glob, name_only); | 1167 | print_hwcache_events(event_glob, name_only); |
1166 | 1168 | ||
1169 | print_pmu_events(event_glob, name_only); | ||
1170 | |||
1167 | if (event_glob != NULL) | 1171 | if (event_glob != NULL) |
1168 | return; | 1172 | return; |
1169 | 1173 | ||
1170 | if (!name_only) { | 1174 | if (!name_only) { |
1171 | printf("\n"); | ||
1172 | printf(" %-50s [%s]\n", | 1175 | printf(" %-50s [%s]\n", |
1173 | "rNNN", | 1176 | "rNNN", |
1174 | event_type_descriptors[PERF_TYPE_RAW]); | 1177 | event_type_descriptors[PERF_TYPE_RAW]); |
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 1d1862dcbbbc..bc9d8069d376 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c | |||
@@ -564,3 +564,76 @@ void perf_pmu__set_format(unsigned long *bits, long from, long to) | |||
564 | for (b = from; b <= to; b++) | 564 | for (b = from; b <= to; b++) |
565 | set_bit(b, bits); | 565 | set_bit(b, bits); |
566 | } | 566 | } |
567 | |||
568 | static char *format_alias(char *buf, int len, struct perf_pmu *pmu, | ||
569 | struct perf_pmu_alias *alias) | ||
570 | { | ||
571 | snprintf(buf, len, "%s/%s/", pmu->name, alias->name); | ||
572 | return buf; | ||
573 | } | ||
574 | |||
575 | static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu, | ||
576 | struct perf_pmu_alias *alias) | ||
577 | { | ||
578 | snprintf(buf, len, "%s OR %s/%s/", alias->name, pmu->name, alias->name); | ||
579 | return buf; | ||
580 | } | ||
581 | |||
582 | static int cmp_string(const void *a, const void *b) | ||
583 | { | ||
584 | const char * const *as = a; | ||
585 | const char * const *bs = b; | ||
586 | return strcmp(*as, *bs); | ||
587 | } | ||
588 | |||
589 | void print_pmu_events(const char *event_glob, bool name_only) | ||
590 | { | ||
591 | struct perf_pmu *pmu; | ||
592 | struct perf_pmu_alias *alias; | ||
593 | char buf[1024]; | ||
594 | int printed = 0; | ||
595 | int len, j; | ||
596 | char **aliases; | ||
597 | |||
598 | pmu = NULL; | ||
599 | len = 0; | ||
600 | while ((pmu = perf_pmu__scan(pmu)) != NULL) | ||
601 | list_for_each_entry(alias, &pmu->aliases, list) | ||
602 | len++; | ||
603 | aliases = malloc(sizeof(char *) * len); | ||
604 | if (!aliases) | ||
605 | return; | ||
606 | pmu = NULL; | ||
607 | j = 0; | ||
608 | while ((pmu = perf_pmu__scan(pmu)) != NULL) | ||
609 | list_for_each_entry(alias, &pmu->aliases, list) { | ||
610 | char *name = format_alias(buf, sizeof(buf), pmu, alias); | ||
611 | bool is_cpu = !strcmp(pmu->name, "cpu"); | ||
612 | |||
613 | if (event_glob != NULL && | ||
614 | !(strglobmatch(name, event_glob) || | ||
615 | (!is_cpu && strglobmatch(alias->name, | ||
616 | event_glob)))) | ||
617 | continue; | ||
618 | aliases[j] = name; | ||
619 | if (is_cpu && !name_only) | ||
620 | aliases[j] = format_alias_or(buf, sizeof(buf), | ||
621 | pmu, alias); | ||
622 | aliases[j] = strdup(aliases[j]); | ||
623 | j++; | ||
624 | } | ||
625 | len = j; | ||
626 | qsort(aliases, len, sizeof(char *), cmp_string); | ||
627 | for (j = 0; j < len; j++) { | ||
628 | if (name_only) { | ||
629 | printf("%s ", aliases[j]); | ||
630 | continue; | ||
631 | } | ||
632 | printf(" %-50s [Kernel PMU event]\n", aliases[j]); | ||
633 | free(aliases[j]); | ||
634 | printed++; | ||
635 | } | ||
636 | if (printed) | ||
637 | printf("\n"); | ||
638 | free(aliases); | ||
639 | } | ||
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index d17b5656bacf..6b2cbe2d4cc3 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h | |||
@@ -3,6 +3,7 @@ | |||
3 | 3 | ||
4 | #include <linux/bitops.h> | 4 | #include <linux/bitops.h> |
5 | #include <linux/perf_event.h> | 5 | #include <linux/perf_event.h> |
6 | #include <stdbool.h> | ||
6 | 7 | ||
7 | enum { | 8 | enum { |
8 | PERF_PMU_FORMAT_VALUE_CONFIG, | 9 | PERF_PMU_FORMAT_VALUE_CONFIG, |
@@ -40,5 +41,7 @@ int perf_pmu__format_parse(char *dir, struct list_head *head); | |||
40 | 41 | ||
41 | struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu); | 42 | struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu); |
42 | 43 | ||
44 | void print_pmu_events(const char *event_glob, bool name_only); | ||
45 | |||
43 | int perf_pmu__test(void); | 46 | int perf_pmu__test(void); |
44 | #endif /* __PMU_H */ | 47 | #endif /* __PMU_H */ |