Messages in this thread Patch in this message | | | From | Wang Nan <> | Subject | [PATCH 10/27] perf tools: Allow BPF placeholder dummy events to collect --filter options | Date | Sun, 6 Sep 2015 07:13:26 +0000 |
| |
This patch improves collection and setting of filters, allows --filter be set to BPF placeholder events (which is a software dummy event).
perf_evsel__is_dummy(), perf_evsel__is_bpf_placeholder() and perf_evsel__can_filter() are introduced for this.
Test result:
# perf record --event dummy --exclude-perf --exclude-perf option should follow a -e tracepoint option
# perf record --event dummy:u --exclude-perf ls --exclude-perf option should follow a -e tracepoint option
# perf record --event test.o --exclude-perf ls Added new event: perf_bpf_probe:func_vfs_write (on vfs_write) ...
# perf record --event dummy.o --exclude-perf ls Added new event: perf_bpf_probe:func_write (on sys_write) ...
Signed-off-by: Wang Nan <wangnan0@huawei.com> Cc: Alexei Starovoitov <ast@plumgrid.com> Cc: Brendan Gregg <brendan.d.gregg@gmail.com> Cc: Daniel Borkmann <daniel@iogearbox.net> Cc: David Ahern <dsahern@gmail.com> Cc: He Kuang <hekuang@huawei.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Kaixu Xia <xiakaixu@huawei.com> Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Zefan Li <lizefan@huawei.com> Cc: pi3orama@163.com Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Link: http://lkml.kernel.org/n/1441518918-149316-1-git-send-email-wangnan0@huawei.com --- tools/perf/util/evlist.c | 7 +++++++ tools/perf/util/evsel.c | 32 ++++++++++++++++++++++++++++++++ tools/perf/util/evsel.h | 23 +++++++++++++++++++++++ tools/perf/util/parse-events.c | 4 ++-- 4 files changed, 64 insertions(+), 2 deletions(-)
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 93db4c1..29212dc 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -1223,6 +1223,13 @@ int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **e continue; /* + * Filters are allowed to be set to dummy event for BPF object + * placeholder. Don't really apply them. + */ + if (perf_evsel__is_dummy(evsel)) + continue; + + /* * filters only work for tracepoint event, which doesn't have cpu limit. * So evlist and evsel should always be same. */ diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 73cf9fc..e307ea2 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -2344,3 +2344,35 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target, err, strerror_r(err, sbuf, sizeof(sbuf)), perf_evsel__name(evsel)); } + +bool perf_evsel__is_bpf_placeholder(struct perf_evsel *evsel) +{ + if (!perf_evsel__is_dummy(evsel)) + return false; + if (!evsel->name) + return false; + /* + * If evsel->name doesn't starts with 'dummy', it must be a BPF + * place holder. + */ + if (strncmp(evsel->name, perf_evsel__sw_names[PERF_COUNT_SW_DUMMY], + strlen(perf_evsel__sw_names[PERF_COUNT_SW_DUMMY]))) + return true; + /* + * Very rare case: evsel->name is 'dummy_crazy.bpf'. + * + * Let's check name suffix. A bpf file should ends with one of: + * '.o', '.c' or '.bpf'. + */ +#define SUFFIX_CMP(s)\ + strcmp(evsel->name + strlen(evsel->name) - (sizeof(s) - 1), s) + + if (SUFFIX_CMP(".o") == 0) + return true; + if (SUFFIX_CMP(".c") == 0) + return true; + if (SUFFIX_CMP(".bpf") == 0) + return true; + return false; +#undef SUFFIX_CMP +} diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index fd22f83..864fd3f 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -372,11 +372,34 @@ bool perf_evsel__fallback(struct perf_evsel *evsel, int err, int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target, int err, char *msg, size_t size); +bool perf_evsel__is_bpf_placeholder(struct perf_evsel *evsel); + static inline int perf_evsel__group_idx(struct perf_evsel *evsel) { return evsel->idx - evsel->leader->idx; } +static inline bool perf_evsel__is_dummy(struct perf_evsel *evsel) +{ + if (!evsel) + return false; + if (evsel->attr.type != PERF_TYPE_SOFTWARE) + return false; + if (evsel->attr.config != PERF_COUNT_SW_DUMMY) + return false; + return true; +} + +static inline int perf_evsel__can_filter(struct perf_evsel *evsel) +{ + if (!evsel) + return false; + if (evsel->attr.type == PERF_TYPE_TRACEPOINT) + return true; + + return perf_evsel__is_bpf_placeholder(evsel); +} + #define for_each_group_member(_evsel, _leader) \ for ((_evsel) = list_entry((_leader)->node.next, struct perf_evsel, node); \ (_evsel) && (_evsel)->leader == (_leader); \ diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index b560f5f..d961e90 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -1346,7 +1346,7 @@ static int set_filter(struct perf_evsel *evsel, const void *arg) { const char *str = arg; - if (evsel == NULL || evsel->attr.type != PERF_TYPE_TRACEPOINT) { + if (!perf_evsel__can_filter(evsel)) { fprintf(stderr, "--filter option should follow a -e tracepoint option\n"); return -1; @@ -1375,7 +1375,7 @@ static int add_exclude_perf_filter(struct perf_evsel *evsel, { char new_filter[64]; - if (evsel == NULL || evsel->attr.type != PERF_TYPE_TRACEPOINT) { + if (!perf_evsel__can_filter(evsel)) { fprintf(stderr, "--exclude-perf option should follow a -e tracepoint option\n"); return -1; -- 2.1.0
| |