diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 83c08037e7e2..49fb7b5feb09 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -210,6 +210,7 @@ void perf_evsel__init(struct perf_evsel *evsel, perf_evsel__object.init(evsel); evsel->sample_size = __perf_evsel__sample_size(attr->sample_type); perf_evsel__calc_id_pos(evsel); + evsel->cmdline_group_boundary = false; } struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx) diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index fe9f3279632b..1fc263a80d91 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -86,6 +86,7 @@ struct perf_evsel { unsigned long *per_pkg_mask; struct perf_evsel *leader; char *group_name; + bool cmdline_group_boundary; }; union u64_swap { diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index a71eeb279ed2..bbb7fbc2857e 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -1065,8 +1065,13 @@ int parse_events(struct perf_evlist *evlist, const char *str, perf_pmu__parse_cleanup(); if (!ret) { int entries = data.idx - evlist->nr_entries; + struct perf_evsel *last; + perf_evlist__splice_list_tail(evlist, &data.list, entries); evlist->nr_groups += data.nr_groups; + last = perf_evlist__last(evlist); + last->cmdline_group_boundary = true; + return 0; } @@ -1171,16 +1176,23 @@ int parse_filter(const struct option *opt, const char *str, if (evlist->nr_entries > 0) last = perf_evlist__last(evlist); - if (last == NULL || last->attr.type != PERF_TYPE_TRACEPOINT) { - fprintf(stderr, - "--filter option should follow a -e tracepoint option\n"); - return -1; - } + do { + if (last == NULL || last->attr.type != PERF_TYPE_TRACEPOINT) { + fprintf(stderr, + "--filter option should follow a -e tracepoint option\n"); + return -1; + } - if (perf_evsel__set_filter(last, str) < 0) { - fprintf(stderr, "not enough memory to hold filter string\n"); - return -1; - } + if (perf_evsel__set_filter(last, str) < 0) { + fprintf(stderr, + "not enough memory to hold filter string\n"); + return -1; + } + + if (last->node.prev == &evlist->entries) + return 0; + last = list_entry(last->node.prev, struct perf_evsel, node); + } while (!last->cmdline_group_boundary); return 0; }