summaryrefslogtreecommitdiffstats
path: root/tools/perf/util/parse-events.c
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@redhat.com>2012-03-20 19:15:40 +0100
committerArnaldo Carvalho de Melo <acme@redhat.com>2012-03-22 15:11:38 -0300
commit5d7be90ed5cfb5dd3c9ab726d7daa91b86b81747 (patch)
tree9b40166a00566af8bef1c388d51b8863a92cc6fe /tools/perf/util/parse-events.c
parent9fafd98f1bf14276f95b69f0186ad5675f1e1a18 (diff)
perf tools: Fix modifier to be applied on correct events
The event modifier needs to be applied only on the event definition it is attached to. The current state is that in case of multiple events definition (in single '-e' option, separated by ',') all will get modifier of the last one. Fixing this by adding separated list for each event definition, so the modifier is applied only to proper event(s). Added automated test to catch this, plus some other modifier tests. Signed-off-by: Jiri Olsa <jolsa@redhat.com> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1332267341-26338-3-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/parse-events.c')
-rw-r--r--tools/perf/util/parse-events.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index f542a631388..5b3a0ef4e23 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -23,7 +23,8 @@ struct event_symbol {
const char *alias;
};
-int parse_events_parse(struct list_head *list, int *idx);
+int parse_events_parse(struct list_head *list, struct list_head *list_tmp,
+ int *idx);
#define CHW(x) .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_##x
#define CSW(x) .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_##x
@@ -671,6 +672,18 @@ int parse_events_add_pmu(struct list_head *list, int *idx,
return add_event(list, idx, &attr, (char *) "pmu");
}
+void parse_events_update_lists(struct list_head *list_event,
+ struct list_head *list_all)
+{
+ /*
+ * Called for single event definition. Update the
+ * 'all event' list, and reinit the 'signle event'
+ * list, for next event definition.
+ */
+ list_splice_tail(list_event, list_all);
+ INIT_LIST_HEAD(list_event);
+}
+
int parse_events_modifier(struct list_head *list, char *str)
{
struct perf_evsel *evsel;
@@ -736,14 +749,14 @@ int parse_events_modifier(struct list_head *list, char *str)
int parse_events(struct perf_evlist *evlist, const char *str, int unset __used)
{
- struct perf_evsel *evsel, *h;
LIST_HEAD(list);
+ LIST_HEAD(list_tmp);
YY_BUFFER_STATE buffer;
int ret, idx = evlist->nr_entries;
buffer = parse_events__scan_string(str);
- ret = parse_events_parse(&list, &idx);
+ ret = parse_events_parse(&list, &list_tmp, &idx);
parse_events__flush_buffer(buffer);
parse_events__delete_buffer(buffer);
@@ -754,9 +767,11 @@ int parse_events(struct perf_evlist *evlist, const char *str, int unset __used)
return 0;
}
- list_for_each_entry_safe(evsel, h, &list, node)
- perf_evsel__delete(evsel);
-
+ /*
+ * There are 2 users - builtin-record and builtin-test objects.
+ * Both call perf_evlist__delete in case of error, so we dont
+ * need to bother.
+ */
fprintf(stderr, "invalid or unsupported event: '%s'\n", str);
fprintf(stderr, "Run 'perf list' for a list of valid events\n");
return ret;