* [PATCH 1/3] perf, tools: Support generic events as pmu event names
2012-10-03 21:22 Tie lose "perf, tools" ends in Haswell PMU patchkit Andi Kleen
@ 2012-10-03 21:22 ` Andi Kleen
2012-10-03 21:22 ` [PATCH 2/3] perf, tools: Default to cpu// for events Andi Kleen
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Andi Kleen @ 2012-10-03 21:22 UTC (permalink / raw)
To: acme; +Cc: jolsa, eranian, a.p.zijlstra, linux-kernel, Andi Kleen
From: Andi Kleen <ak@linux.intel.com>
Extend the parser/lexer to allow generic event names like,
"instructions" as a sysfs supplied PMU event name too.
This resolves the problem that cpu/instructions/ gives a parse
error, even when the kernel supplies a "instructions" event
This is useful to add sysfs specified qualifiers to these
events, for example cpu/instructions,intx=1/ and needed
for the TSX events
Simply extend the grammar to handle this case. The lexer
needs minor changes to save the original string.
Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
tools/perf/util/parse-events.l | 3 ++-
tools/perf/util/parse-events.y | 27 +++++++++++++++++++++++----
2 files changed, 25 insertions(+), 5 deletions(-)
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index c2e5142..dd3a901 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -55,7 +55,8 @@ static int sym(yyscan_t scanner, int type, int config)
{
YYSTYPE *yylval = parse_events_get_lval(scanner);
- yylval->num = (type << 16) + config;
+ yylval->namenum.num = (type << 16) + config;
+ yylval->namenum.name = strdup(parse_events_get_text(scanner));
return type == PERF_TYPE_HARDWARE ? PE_VALUE_SYM_HW : PE_VALUE_SYM_SW;
}
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index cd88209..5b26ad3 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -34,8 +34,8 @@ do { \
%token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP
%token PE_ERROR
%type <num> PE_VALUE
-%type <num> PE_VALUE_SYM_HW
-%type <num> PE_VALUE_SYM_SW
+%type <namenum> PE_VALUE_SYM_HW
+%type <namenum> PE_VALUE_SYM_SW
%type <num> PE_RAW
%type <num> PE_TERM
%type <str> PE_NAME
@@ -65,6 +65,7 @@ do { \
%union
{
+ struct { char *name; u64 num; } namenum;
char *str;
u64 num;
struct list_head *head;
@@ -195,9 +196,9 @@ PE_NAME '/' event_config '/'
}
value_sym:
-PE_VALUE_SYM_HW
+PE_VALUE_SYM_HW { free($1.name); return $1.num; }
|
-PE_VALUE_SYM_SW
+PE_VALUE_SYM_SW { free($1.name); return $1.num; }
event_legacy_symbol:
value_sym '/' event_config '/'
@@ -361,6 +362,24 @@ PE_NAME
$$ = term;
}
|
+PE_VALUE_SYM_HW
+{
+ struct parse_events__term *term;
+
+ ABORT_ON(parse_events__term_num(&term, PARSE_EVENTS__TERM_TYPE_USER,
+ $1.name, 1));
+ $$ = term;
+}
+|
+PE_VALUE_SYM_SW
+{
+ struct parse_events__term *term;
+
+ ABORT_ON(parse_events__term_num(&term, PARSE_EVENTS__TERM_TYPE_USER,
+ $1.name, 1));
+ $$ = term;
+}
+|
PE_TERM '=' PE_NAME
{
struct parse_events__term *term;
--
1.7.7.6
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 2/3] perf, tools: Default to cpu// for events
2012-10-03 21:22 Tie lose "perf, tools" ends in Haswell PMU patchkit Andi Kleen
2012-10-03 21:22 ` [PATCH 1/3] perf, tools: Support generic events as pmu event names Andi Kleen
@ 2012-10-03 21:22 ` Andi Kleen
2012-10-03 21:22 ` [PATCH 3/3] perf, tools: List kernel supplied event aliases in perf list Andi Kleen
2012-10-06 14:57 ` Tie lose "perf, tools" ends in Haswell PMU patchkit Jan Ceuleers
3 siblings, 0 replies; 6+ messages in thread
From: Andi Kleen @ 2012-10-03 21:22 UTC (permalink / raw)
To: acme; +Cc: jolsa, eranian, a.p.zijlstra, linux-kernel, Andi Kleen
From: Andi Kleen <ak@linux.intel.com>
When an event fails to parse and it's not in a new style format,
try to parse it again as a cpu event.
This allows to use sysfs exported events directly without //, so I can use
perf record -e tx-aborts ...
instead of
perf record -e cpu/tx-aborts/
Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
tools/perf/util/parse-events.c | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index de1cb9e..4e7117f 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -785,6 +785,16 @@ static int parse_events__scanner(const char *str, void *data, int start_token)
parse_events__flush_buffer(buffer, scanner);
parse_events__delete_buffer(buffer, scanner);
parse_events_lex_destroy(scanner);
+
+ if (ret && !strchr(str, '/')) {
+ char *s = malloc(strlen(str) + strlen("cpu/") + 2);
+
+ if (!s)
+ return ret;
+ sprintf(s, "cpu/%s/", str);
+ str = s;
+ return parse_events__scanner(str, data, start_token);
+ }
return ret;
}
--
1.7.7.6
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 3/3] perf, tools: List kernel supplied event aliases in perf list
2012-10-03 21:22 Tie lose "perf, tools" ends in Haswell PMU patchkit Andi Kleen
2012-10-03 21:22 ` [PATCH 1/3] perf, tools: Support generic events as pmu event names Andi Kleen
2012-10-03 21:22 ` [PATCH 2/3] perf, tools: Default to cpu// for events Andi Kleen
@ 2012-10-03 21:22 ` Andi Kleen
2012-10-06 14:57 ` Tie lose "perf, tools" ends in Haswell PMU patchkit Jan Ceuleers
3 siblings, 0 replies; 6+ messages in thread
From: Andi Kleen @ 2012-10-03 21:22 UTC (permalink / raw)
To: acme; +Cc: jolsa, eranian, a.p.zijlstra, linux-kernel, Andi Kleen
From: Andi Kleen <ak@linux.intel.com>
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>
---
tools/perf/Documentation/perf-list.txt | 4 +-
tools/perf/builtin-list.c | 3 +
tools/perf/util/parse-events.c | 5 ++-
tools/perf/util/pmu.c | 71 ++++++++++++++++++++++++++++++++
tools/perf/util/pmu.h | 3 +
5 files changed, 84 insertions(+), 2 deletions(-)
diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt
index d1e39dc..826f3d6 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
SYNOPSIS
--------
[verse]
-'perf list' [hw|sw|cache|tracepoint|event_glob]
+'perf list' [hw|sw|cache|tracepoint|pmu|event_glob]
DESCRIPTION
-----------
@@ -104,6 +104,8 @@ To limit the list use:
'subsys_glob:event_glob' to filter by tracepoint subsystems such as sched,
block, etc.
+. 'pmu' to print the kernel supplied PMU events.
+
. If none of the above is matched, it will apply the supplied glob to all
events, printing the ones that match.
diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c
index 1948ece..e79f423 100644
--- a/tools/perf/builtin-list.c
+++ b/tools/perf/builtin-list.c
@@ -13,6 +13,7 @@
#include "util/parse-events.h"
#include "util/cache.h"
+#include "util/pmu.h"
int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
{
@@ -37,6 +38,8 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
else if (strcmp(argv[i], "cache") == 0 ||
strcmp(argv[i], "hwcache") == 0)
print_hwcache_events(NULL, false);
+ else if (strcmp(argv[i], "pmu") == 0)
+ print_pmu_events(NULL, false);
else if (strcmp(argv[i], "--raw-dump") == 0)
print_events(NULL, true);
else {
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 4e7117f..0b1a4b1 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1033,6 +1033,8 @@ int print_hwcache_events(const char *event_glob, bool name_only)
}
}
+ if (printed)
+ printf("\n");
return printed;
}
@@ -1087,11 +1089,12 @@ void print_events(const char *event_glob, bool name_only)
print_hwcache_events(event_glob, name_only);
+ print_pmu_events(event_glob, name_only);
+
if (event_glob != NULL)
return;
if (!name_only) {
- printf("\n");
printf(" %-50s [%s]\n",
"rNNN",
event_type_descriptors[PERF_TYPE_RAW]);
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 8a2229d..c0d2fc9 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -551,6 +551,77 @@ void perf_pmu__set_format(unsigned long *bits, long from, long to)
set_bit(b, bits);
}
+static char *format_alias(char *buf, int len, struct perf_pmu *pmu,
+ struct perf_pmu__alias *alias)
+{
+ snprintf(buf, len, "%s/%s/", pmu->name, alias->name);
+ return buf;
+}
+
+static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu,
+ struct perf_pmu__alias *alias)
+{
+ snprintf(buf, len, "%s OR %s/%s/", alias->name, pmu->name, alias->name);
+ return buf;
+}
+
+static int cmp_string(const void *a, const void *b)
+{
+ const char * const *as = a;
+ const char * const *bs = b;
+ return strcmp(*as, *bs);
+}
+
+void print_pmu_events(const char *event_glob, bool name_only)
+{
+ struct perf_pmu *pmu;
+ struct perf_pmu__alias *alias;
+ char buf[1024];
+ int printed = 0;
+ int len, j;
+ char **aliases;
+
+ pmu = NULL;
+ len = 0;
+ while ((pmu = perf_pmu__scan(pmu)) != NULL)
+ list_for_each_entry (alias, &pmu->aliases, list)
+ len++;
+ aliases = malloc(sizeof(char *) * len);
+ if (!aliases)
+ return;
+ pmu = NULL;
+ j = 0;
+ while ((pmu = perf_pmu__scan(pmu)) != NULL)
+ list_for_each_entry (alias, &pmu->aliases, list) {
+ char *name = format_alias(buf, sizeof buf, pmu, alias);
+ bool is_cpu = !strcmp(pmu->name, "cpu");
+
+ if (event_glob != NULL &&
+ !(strglobmatch(name, event_glob) ||
+ (!is_cpu && strglobmatch(alias->name, event_glob))))
+ continue;
+ aliases[j] = name;
+ if (is_cpu && !name_only)
+ aliases[j] = format_alias_or(buf, sizeof buf,
+ pmu, alias);
+ aliases[j] = strdup(aliases[j]);
+ j++;
+ }
+ qsort(aliases, len, sizeof(char *), cmp_string);
+ for (j = 0; j < len; j++) {
+ if (name_only) {
+ printf("%s ", aliases[j]);
+ continue;
+ }
+ printf(" %-50s [Kernel PMU event]\n", aliases[j]);
+ free(aliases[j]);
+ printed++;
+ }
+ if (printed)
+ printf("\n");
+ free(aliases);
+}
+
/* Simulated format definitions. */
static struct test_format {
const char *name;
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index 53c7794..b4e0203 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -3,6 +3,7 @@
#include <linux/bitops.h>
#include "../../../include/linux/perf_event.h"
+#include <stdbool.h>
enum {
PERF_PMU_FORMAT_VALUE_CONFIG,
@@ -49,5 +50,7 @@ void perf_pmu__set_format(unsigned long *bits, long from, long to);
struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu);
+void print_pmu_events(const char *event_glob, bool name_only);
+
int perf_pmu__test(void);
#endif /* __PMU_H */
--
1.7.7.6
^ permalink raw reply related [flat|nested] 6+ messages in thread