lkml.org 
[lkml]   [2015]   [Sep]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH] perf tools: Allow BPF placeholder dummy events to collect --filter options
Date
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>
---
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;
--
1.8.3.4


\
 
 \ /
  Last update: 2015-09-06 08:21    [W:0.182 / U:15.028 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site