[PATCH 08/10] perf, tools: Expand PMU events by prefix match

2016-11-18 Thread Andi Kleen
From: Andi Kleen 

When the user specifies a pmu directly, expand it automatically
with a prefix match, similar as we do for the normal aliases now.

This allows to specify attributes for duplicated boxes quickly.
For example uncore_cbox_{0,6}/.../ can be now specified as cbox/.../
and it gets automatically expanded.

Before

% perf stat -a -e uncore_cbox_0/event=0x35,umask=0x1,filter_opc=0x19C/,\
uncore_cbox_1/event=0x35,umask=0x1,filter_opc=0x19C/,\
uncore_cbox_2/event=0x35,umask=0x1,filter_opc=0x19C/,\
uncore_cbox_3/event=0x35,umask=0x1,filter_opc=0x19C/,\
uncore_cbox_4/event=0x35,umask=0x1,filter_opc=0x19C/,\
uncore_cbox_5/event=0x35,umask=0x1,filter_opc=0x19C/ sleep 1

After

perf stat -a -e cbox/event=0x35,umask=0x1,filter_opc=0x19C/ sleep 1

v2: Handle all bison rules. Move multi add code to separate function.
Handle uncore_ prefix correctly.
Signed-off-by: Andi Kleen 
---
 tools/perf/util/parse-events.c | 71 
 tools/perf/util/parse-events.h |  8 +
 tools/perf/util/parse-events.y | 73 +-
 3 files changed, 109 insertions(+), 43 deletions(-)

diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 6dbcba7f0969..fba53ba22431 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1257,6 +1257,52 @@ int parse_events_add_pmu(struct parse_events_evlist 
*data,
return evsel ? 0 : -ENOMEM;
 }
 
+int parse_events_multi_pmu_add(struct parse_events_evlist *data,
+  char *str, struct list_head **listp)
+{
+   struct list_head *head;
+   struct parse_events_term *term;
+   struct list_head *list;
+   struct perf_pmu *pmu = NULL;
+   int ok = 0;
+
+   *listp = NULL;
+   /* Add it for all PMUs that support the alias */
+   list = malloc(sizeof(struct list_head));
+   if (!list)
+   return -1;
+   INIT_LIST_HEAD(list);
+   while ((pmu = perf_pmu__scan(pmu)) != NULL) {
+   struct perf_pmu_alias *alias;
+
+   list_for_each_entry(alias, &pmu->aliases, list) {
+   if (!strcasecmp(alias->name, str)) {
+   head = malloc(sizeof(struct list_head));
+   if (!head)
+   return -1;
+   INIT_LIST_HEAD(head);
+   if (parse_events_term__num(&term, 
PARSE_EVENTS__TERM_TYPE_USER,
+  str, 1, &str, NULL) 
< 0)
+   return -1;
+   list_add_tail(&term->list, head);
+
+   if (!parse_events_add_pmu(data, list,
+ pmu->name, head)) {
+   pr_debug("%s -> %s/%s/\n", str,
+pmu->name, alias->str);
+   ok++;
+   }
+
+   parse_events_terms__delete(head);
+   }
+   }
+   }
+   if (!ok)
+   return -1;
+   *listp = list;
+   return 0;
+}
+
 int parse_events__modifier_group(struct list_head *list,
 char *event_mod)
 {
@@ -2406,6 +2452,31 @@ int parse_events_term__clone(struct parse_events_term 
**new,
term->err_term, term->err_val);
 }
 
+int parse_events_copy_term_list(struct list_head *old,
+struct list_head **new)
+{
+   struct parse_events_term *term, *n;
+   int ret;
+
+   if (!old) {
+   *new = NULL;
+   return 0;
+   }
+
+   *new = malloc(sizeof(struct list_head));
+   if (!*new)
+   return -ENOMEM;
+   INIT_LIST_HEAD(*new);
+
+   list_for_each_entry (term, old, list) {
+   ret = parse_events_term__clone(&n, term);
+   if (ret)
+   return ret;
+   list_add_tail(&n->list, *new);
+   }
+   return 0;
+}
+
 void parse_events_terms__purge(struct list_head *terms)
 {
struct parse_events_term *term, *h;
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index da246a3ddb69..33b3e52cd9b8 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -164,6 +164,14 @@ int parse_events_add_breakpoint(struct list_head *list, 
int *idx,
 int parse_events_add_pmu(struct parse_events_evlist *data,
 struct list_head *list, char *name,
 struct list_head *head_config);
+
+int parse_events_multi_pmu_add(struct parse_events_evlist *data,
+  char *str,
+  struct list_head **listp);
+
+int parse_events_copy_term_list(struct list_head *old,
+ 

Re: [PATCH 08/10] perf, tools: Expand PMU events by prefix match

2016-10-17 Thread Jiri Olsa
On Mon, Oct 17, 2016 at 09:56:42AM -0700, Andi Kleen wrote:
> > so there's a special treatment for uncore events,
> > what if user says 'uncore_box/..' then?
> 
> It should work. There's nothing special for uncore later, this
> is just for convenience so that I have less to type.

really..


'uncore_cbox_0/clockticks/'

[jolsa@krava perf]$ sudo ./perf stat -e 'uncore_cbox_0/clockticks/' -a
^C
 Performance counter stats for 'system wide':

 0  uncore_cbox_0/clockticks/   


   0.676237018 seconds time elapsed


'cbox_0/clockticks/'

[jolsa@krava perf]$ sudo ./perf stat -e 'cbox_0/clockticks/' -a
^C
 Performance counter stats for 'system wide':

 0  cbox_0/clockticks/  


   0.991623038 seconds time elapsed


'cbox/clockticks'

[jolsa@krava perf]$ sudo ./perf stat -e 'cbox/clockticks/' -a
^C
 Performance counter stats for 'system wide':

 0  cbox/clockticks/


   0.708006656 seconds time elapsed


'uncore_cbox/clockticks/'

[jolsa@krava perf]$ sudo ./perf stat -e 'uncore_cbox/clockticks/' -a
invalid or unsupported event: 'uncore_cbox/clockticks/'
Run 'perf list' for a list of valid events

 Usage: perf stat [] []

-e, --eventevent selector. use 'perf list' to list 
available events


jirka


Re: [PATCH 08/10] perf, tools: Expand PMU events by prefix match

2016-10-17 Thread Andi Kleen
> so there's a special treatment for uncore events,
> what if user says 'uncore_box/..' then?

It should work. There's nothing special for uncore later, this
is just for convenience so that I have less to type.

> > +   if (!strncmp($1, name, strlen($1))) {
> > +   if (parse_events_copy_term_list(orig_terms, 
> > &terms))
> > +   YYABORT;
> > +   if (!parse_events_add_pmu(data, list, 
> > pmu->name, terms))
> > +   ok++;
> 
> so we're ok if some of the events is not added?
> do we warn at least?

It would warn a lot because most PMUs don't have a given aliases.
So you would get an warning for every extra PMU.

Trying to warn only for those that have the alias would need a lot
of extra tracking, and it didn't seem worth the complexity.

-Andi


Re: [PATCH 08/10] perf, tools: Expand PMU events by prefix match

2016-10-17 Thread Jiri Olsa
On Thu, Oct 13, 2016 at 02:15:30PM -0700, Andi Kleen wrote:

SNIP

> diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
> index 3a5196380609..790f0dd598b9 100644
> --- a/tools/perf/util/parse-events.y
> +++ b/tools/perf/util/parse-events.y
> @@ -224,11 +224,34 @@ event_pmu:
>  PE_NAME opt_event_config
>  {
>   struct parse_events_evlist *data = _data;
> - struct list_head *list;
> + struct list_head *list, *orig_terms, *terms;
> +
> + if (parse_events_copy_term_list($2, &orig_terms))
> + YYABORT;
>  
>   ALLOC_LIST(list);
> - ABORT_ON(parse_events_add_pmu(data, list, $1, $2));
> + if (parse_events_add_pmu(data, list, $1, $2)) {
> + struct perf_pmu *pmu = NULL;
> + int ok = 0;
> +
> + while ((pmu = perf_pmu__scan(pmu)) != NULL) {
> + char *name = pmu->name;
> +
> + if (!strncmp(name, "uncore_", 7))
> + name += 7;

so there's a special treatment for uncore events,
what if user says 'uncore_box/..' then?


> + if (!strncmp($1, name, strlen($1))) {
> + if (parse_events_copy_term_list(orig_terms, 
> &terms))
> + YYABORT;
> + if (!parse_events_add_pmu(data, list, 
> pmu->name, terms))
> + ok++;

so we're ok if some of the events is not added?
do we warn at least?

thanks,
jirka


Re: [PATCH 08/10] perf, tools: Expand PMU events by prefix match

2016-10-17 Thread Jiri Olsa
On Thu, Oct 13, 2016 at 02:15:30PM -0700, Andi Kleen wrote:
> From: Andi Kleen 
> 
> When the user specifies a pmu directly, expand it automatically
> with a prefix match, similar as we do for the normal aliases now.
> 
> This allows to specify attributes for duplicated boxes quickly.
> For example uncore_cbox_{0,8}/.../ can be now specified as cbox/.../
> and it gets automatically expanded.

so expand here means adding all the events, right?

could you please state and example and make clear what happens as outcome

thanks,
jirka


[PATCH 08/10] perf, tools: Expand PMU events by prefix match

2016-10-13 Thread Andi Kleen
From: Andi Kleen 

When the user specifies a pmu directly, expand it automatically
with a prefix match, similar as we do for the normal aliases now.

This allows to specify attributes for duplicated boxes quickly.
For example uncore_cbox_{0,8}/.../ can be now specified as cbox/.../
and it gets automatically expanded.

Signed-off-by: Andi Kleen 
---
 tools/perf/util/parse-events.c | 25 +
 tools/perf/util/parse-events.h |  3 +++
 tools/perf/util/parse-events.y | 27 +--
 3 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index a2bbd17a0dc3..8b2333278988 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -2399,6 +2399,31 @@ int parse_events_term__clone(struct parse_events_term 
**new,
term->err_term, term->err_val);
 }
 
+int parse_events_copy_term_list(struct list_head *old,
+struct list_head **new)
+{
+   struct parse_events_term *term, *n;
+   int ret;
+
+   if (!old) {
+   *new = NULL;
+   return 0;
+   }
+
+   *new = malloc(sizeof(struct list_head));
+   if (!*new)
+   return -ENOMEM;
+   INIT_LIST_HEAD(*new);
+
+   list_for_each_entry (term, old, list) {
+   ret = parse_events_term__clone(&n, term);
+   if (ret)
+   return ret;
+   list_add_tail(&n->list, *new);
+   }
+   return 0;
+}
+
 void parse_events_terms__purge(struct list_head *terms)
 {
struct parse_events_term *term, *h;
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index da246a3ddb69..7ea95c35095c 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -164,6 +164,9 @@ int parse_events_add_breakpoint(struct list_head *list, int 
*idx,
 int parse_events_add_pmu(struct parse_events_evlist *data,
 struct list_head *list, char *name,
 struct list_head *head_config);
+int parse_events_copy_term_list(struct list_head *old,
+struct list_head **new);
+
 enum perf_pmu_event_symbol_type
 perf_pmu__parse_check(const char *name);
 void parse_events__set_leader(char *name, struct list_head *list);
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index 3a5196380609..790f0dd598b9 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -224,11 +224,34 @@ event_pmu:
 PE_NAME opt_event_config
 {
struct parse_events_evlist *data = _data;
-   struct list_head *list;
+   struct list_head *list, *orig_terms, *terms;
+
+   if (parse_events_copy_term_list($2, &orig_terms))
+   YYABORT;
 
ALLOC_LIST(list);
-   ABORT_ON(parse_events_add_pmu(data, list, $1, $2));
+   if (parse_events_add_pmu(data, list, $1, $2)) {
+   struct perf_pmu *pmu = NULL;
+   int ok = 0;
+
+   while ((pmu = perf_pmu__scan(pmu)) != NULL) {
+   char *name = pmu->name;
+
+   if (!strncmp(name, "uncore_", 7))
+   name += 7;
+   if (!strncmp($1, name, strlen($1))) {
+   if (parse_events_copy_term_list(orig_terms, 
&terms))
+   YYABORT;
+   if (!parse_events_add_pmu(data, list, 
pmu->name, terms))
+   ok++;
+   parse_events_terms__delete(terms);
+   }
+   }
+   if (!ok)
+   YYABORT;
+   }
parse_events_terms__delete($2);
+   parse_events_terms__delete(orig_terms);
$$ = list;
 }
 |
-- 
2.5.5