mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 20:51:44 +00:00
perf tools: Apply tracepoint event definition options to BPF script
Users can pass options to tracepoints defined in the BPF script. For example: # perf record -e ./test.c/no-inherit/ bash # dd if=/dev/zero of=/dev/null count=10000 # exit [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.022 MB perf.data (139 samples) ] (no-inherit works, only the sys_read issued by bash are captured, at least 10000 sys_read issued by dd are skipped.) test.c: #define SEC(NAME) __attribute__((section(NAME), used)) SEC("func=sys_read") int bpf_func__sys_read(void *ctx) { return 1; } char _license[] SEC("license") = "GPL"; int _version SEC("version") = LINUX_VERSION_CODE; no-inherit is applied to the kprobe event defined in test.c. Signed-off-by: Wang Nan <wangnan0@huawei.com> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexei Starovoitov <ast@kernel.org> Cc: Brendan Gregg <brendan.d.gregg@gmail.com> Cc: Cody P Schafer <dev@codyps.com> Cc: He Kuang <hekuang@huawei.com> Cc: Jeremie Galarneau <jeremie.galarneau@efficios.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Kirill Smelkov <kirr@nexedi.com> Cc: Li Zefan <lizefan@huawei.com> Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Zefan Li <lizefan@huawei.com> Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1456132275-98875-10-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
e571e029bd
commit
95088a591e
@ -112,7 +112,7 @@ static int do_test(struct bpf_object *obj, int (*func)(void),
|
||||
parse_evlist.error = &parse_error;
|
||||
INIT_LIST_HEAD(&parse_evlist.list);
|
||||
|
||||
err = parse_events_load_bpf_obj(&parse_evlist, &parse_evlist.list, obj);
|
||||
err = parse_events_load_bpf_obj(&parse_evlist, &parse_evlist.list, obj, NULL);
|
||||
if (err || list_empty(&parse_evlist.list)) {
|
||||
pr_debug("Failed to add events selected by BPF\n");
|
||||
return TEST_FAIL;
|
||||
|
@ -581,6 +581,7 @@ static int add_tracepoint_multi_sys(struct list_head *list, int *idx,
|
||||
struct __add_bpf_event_param {
|
||||
struct parse_events_evlist *data;
|
||||
struct list_head *list;
|
||||
struct list_head *head_config;
|
||||
};
|
||||
|
||||
static int add_bpf_event(struct probe_trace_event *tev, int fd,
|
||||
@ -597,7 +598,8 @@ static int add_bpf_event(struct probe_trace_event *tev, int fd,
|
||||
tev->group, tev->event, fd);
|
||||
|
||||
err = parse_events_add_tracepoint(&new_evsels, &evlist->idx, tev->group,
|
||||
tev->event, evlist->error, NULL);
|
||||
tev->event, evlist->error,
|
||||
param->head_config);
|
||||
if (err) {
|
||||
struct perf_evsel *evsel, *tmp;
|
||||
|
||||
@ -622,11 +624,12 @@ static int add_bpf_event(struct probe_trace_event *tev, int fd,
|
||||
|
||||
int parse_events_load_bpf_obj(struct parse_events_evlist *data,
|
||||
struct list_head *list,
|
||||
struct bpf_object *obj)
|
||||
struct bpf_object *obj,
|
||||
struct list_head *head_config)
|
||||
{
|
||||
int err;
|
||||
char errbuf[BUFSIZ];
|
||||
struct __add_bpf_event_param param = {data, list};
|
||||
struct __add_bpf_event_param param = {data, list, head_config};
|
||||
static bool registered_unprobe_atexit = false;
|
||||
|
||||
if (IS_ERR(obj) || !obj) {
|
||||
@ -720,14 +723,47 @@ parse_events_config_bpf(struct parse_events_evlist *data,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Split config terms:
|
||||
* perf record -e bpf.c/call-graph=fp,map:array.value[0]=1/ ...
|
||||
* 'call-graph=fp' is 'evt config', should be applied to each
|
||||
* events in bpf.c.
|
||||
* 'map:array.value[0]=1' is 'obj config', should be processed
|
||||
* with parse_events_config_bpf.
|
||||
*
|
||||
* Move object config terms from the first list to obj_head_config.
|
||||
*/
|
||||
static void
|
||||
split_bpf_config_terms(struct list_head *evt_head_config,
|
||||
struct list_head *obj_head_config)
|
||||
{
|
||||
struct parse_events_term *term, *temp;
|
||||
|
||||
/*
|
||||
* Currectly, all possible user config term
|
||||
* belong to bpf object. parse_events__is_hardcoded_term()
|
||||
* happends to be a good flag.
|
||||
*
|
||||
* See parse_events_config_bpf() and
|
||||
* config_term_tracepoint().
|
||||
*/
|
||||
list_for_each_entry_safe(term, temp, evt_head_config, list)
|
||||
if (!parse_events__is_hardcoded_term(term))
|
||||
list_move_tail(&term->list, obj_head_config);
|
||||
}
|
||||
|
||||
int parse_events_load_bpf(struct parse_events_evlist *data,
|
||||
struct list_head *list,
|
||||
char *bpf_file_name,
|
||||
bool source,
|
||||
struct list_head *head_config)
|
||||
{
|
||||
struct bpf_object *obj;
|
||||
int err;
|
||||
struct bpf_object *obj;
|
||||
LIST_HEAD(obj_head_config);
|
||||
|
||||
if (head_config)
|
||||
split_bpf_config_terms(head_config, &obj_head_config);
|
||||
|
||||
obj = bpf__prepare_load(bpf_file_name, source);
|
||||
if (IS_ERR(obj)) {
|
||||
@ -749,10 +785,18 @@ int parse_events_load_bpf(struct parse_events_evlist *data,
|
||||
return err;
|
||||
}
|
||||
|
||||
err = parse_events_load_bpf_obj(data, list, obj);
|
||||
err = parse_events_load_bpf_obj(data, list, obj, head_config);
|
||||
if (err)
|
||||
return err;
|
||||
return parse_events_config_bpf(data, obj, head_config);
|
||||
err = parse_events_config_bpf(data, obj, &obj_head_config);
|
||||
|
||||
/*
|
||||
* Caller doesn't know anything about obj_head_config,
|
||||
* so combine them together again before returnning.
|
||||
*/
|
||||
if (head_config)
|
||||
list_splice_tail(&obj_head_config, head_config);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -146,7 +146,8 @@ int parse_events_load_bpf(struct parse_events_evlist *data,
|
||||
struct bpf_object;
|
||||
int parse_events_load_bpf_obj(struct parse_events_evlist *data,
|
||||
struct list_head *list,
|
||||
struct bpf_object *obj);
|
||||
struct bpf_object *obj,
|
||||
struct list_head *head_config);
|
||||
int parse_events_add_numeric(struct parse_events_evlist *data,
|
||||
struct list_head *list,
|
||||
u32 type, u64 config,
|
||||
|
Loading…
Reference in New Issue
Block a user