Hi,
On Wed, Oct 14, 2015 at 12:41:37PM +0000, Wang Nan wrote:
From: He Kuang <hekuang@xxxxxxxxxx>What about using event name directly? I guess the alias name is used
This patch adds new bison rules for specifying an alias name to a perf
event, which allows cmdline refer to previous defined perf event through
its name. With this patch user can give alias name to a perf event using
following cmdline:
# perf record -e mypmu=cycles ...
To allow parser refer to existing event selecter, pass event list to
'struct parse_events_evlist'. perf_evlist__find_evsel_by_alias() is
introduced to get evsel through its alias.
only to refer an event so it'd be better to use the event name.
Anyway we need alias as well when event has no name or name is complex.
Thanks
Namhyung
Signed-off-by: He Kuang <hekuang@xxxxxxxxxx>
Signed-off-by: Wang Nan <wangnan0@xxxxxxxxxx>
Cc: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
Cc: Alexei Starovoitov <ast@xxxxxxxxxxxx>
Cc: Brendan Gregg <brendan.d.gregg@xxxxxxxxx>
Cc: Daniel Borkmann <daniel@xxxxxxxxxxxxx>
Cc: David Ahern <dsahern@xxxxxxxxx>
Cc: He Kuang <hekuang@xxxxxxxxxx>
Cc: Jiri Olsa <jolsa@xxxxxxxxxx>
Cc: Kaixu Xia <xiakaixu@xxxxxxxxxx>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@xxxxxxxxxxx>
Cc: Namhyung Kim <namhyung@xxxxxxxxxx>
Cc: Paul Mackerras <paulus@xxxxxxxxx>
Cc: Peter Zijlstra <a.p.zijlstra@xxxxxxxxx>
Cc: Zefan Li <lizefan@xxxxxxxxxx>
Cc: pi3orama@xxxxxxx
Link: http://lkml.kernel.org/n/ebpf-7w1s62o0s6ovqlaqwrmx20v9@xxxxxxxxxxxxxx
---
tools/perf/util/evlist.c | 16 ++++++++++++++++
tools/perf/util/evlist.h | 4 ++++
tools/perf/util/evsel.h | 1 +
tools/perf/util/parse-events.c | 31 ++++++++++++++++++++++++++++---
tools/perf/util/parse-events.h | 5 +++++
tools/perf/util/parse-events.y | 15 ++++++++++++++-
6 files changed, 68 insertions(+), 4 deletions(-)
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index d139219..8dd59aa 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -1753,3 +1753,19 @@ void perf_evlist__set_tracking_event(struct perf_evlist *evlist,
tracking_evsel->tracking = true;
}
+
+struct perf_evsel *
+perf_evlist__find_evsel_by_alias(struct perf_evlist *evlist,
+ const char *alias)
+{
+ struct perf_evsel *evsel;
+
+ evlist__for_each(evlist, evsel) {
+ if (!evsel->alias)
+ continue;
+ if (strcmp(alias, evsel->alias) == 0)
+ return evsel;
+ }
+
+ return NULL;
+}
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index a459fe7..4e25342 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -292,4 +292,8 @@ void perf_evlist__set_tracking_event(struct perf_evlist *evlist,
struct perf_evsel *tracking_evsel);
void perf_event_attr__set_max_precise_ip(struct perf_event_attr *attr);
+
+struct perf_evsel *
+perf_evlist__find_evsel_by_alias(struct perf_evlist *evlist, const char *alias);
+
#endif /* __PERF_EVLIST_H */
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index a60b5d5..9a95e73 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -87,6 +87,7 @@ struct perf_evsel {
int idx;
u32 ids;
char *name;
+ char *alias;
double scale;
const char *unit;
struct event_format *tp_format;
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 4849dbd..06ba5a6 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1020,6 +1020,30 @@ int parse_events__modifier_group(struct list_head *list,
return parse_events__modifier_event(list, event_mod, true);
}
+int parse_events__set_event_alias(struct parse_events_evlist *data,
+ struct list_head *list,
+ const char *str,
+ void *loc_alias_)
+{
+ struct perf_evsel *evsel;
+ YYLTYPE *loc_alias = loc_alias_;
+
+ if (!str)
+ return 0;
+
+ if (!list_is_singular(list)) {
+ struct parse_events_error *err = data->error;
+
+ err->idx = loc_alias->first_column;
+ err->str = strdup("One alias can be applied to one event only");
+ return -EINVAL;
+ }
+
+ evsel = list_first_entry(list, struct perf_evsel, node);
+ evsel->alias = strdup(str);
+ return evsel->alias ? 0 : -ENOMEM;
+}
+
void parse_events__set_leader(char *name, struct list_head *list)
{
struct perf_evsel *leader;
@@ -1373,9 +1397,10 @@ int parse_events(struct perf_evlist *evlist, const char *str,
struct parse_events_error *err)
{
struct parse_events_evlist data = {
- .list = LIST_HEAD_INIT(data.list),
- .idx = evlist->nr_entries,
- .error = err,
+ .list = LIST_HEAD_INIT(data.list),
+ .idx = evlist->nr_entries,
+ .error = err,
+ .evlist = evlist,
};
int ret;
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index 8f17c83..b525353 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -96,6 +96,7 @@ struct parse_events_evlist {
int idx;
int nr_groups;
struct parse_events_error *error;
+ struct perf_evlist *evlist;
};
struct parse_events_terms {
@@ -168,4 +169,8 @@ extern int is_valid_tracepoint(const char *event_string);
int valid_event_mount(const char *eventfs);
char *parse_events_formats_error_string(char *additional_terms);
+int parse_events__set_event_alias(struct parse_events_evlist *data,
+ struct list_head *list,
+ const char *str,
+ void *loc_alias_);
#endif /* __PERF_PARSE_EVENTS_H */
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index ad37996..90e382f 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -76,6 +76,7 @@ static inc_group_count(struct list_head *list,
%type <head> event_bpf_file
%type <head> event_def
%type <head> event_mod
+%type <head> event_alias
%type <head> event_name
%type <head> event
%type <head> events
@@ -192,13 +193,25 @@ event_name PE_MODIFIER_EVENT
event_name
event_name:
-PE_EVENT_NAME event_def
+PE_EVENT_NAME event_alias
{
ABORT_ON(parse_events_name($2, $1));
free($1);
$$ = $2;
}
|
+event_alias
+
+event_alias:
+PE_NAME '=' event_def
+{
+ struct list_head *list = $3;
+ struct parse_events_evlist *data = _data;
+
+ ABORT_ON(parse_events__set_event_alias(data, list, $1, &@1));
+ $$ = list;
+}
+|
event_def
event_def: event_pmu |
--
1.8.3.4