lkml.org 
[lkml]   [2016]   [Feb]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[tip:perf/core] perf tools: Apply tracepoint event definition options to BPF script
    Commit-ID:  95088a591e197610bd03f4059f5fdbe9e376425b
    Gitweb: http://git.kernel.org/tip/95088a591e197610bd03f4059f5fdbe9e376425b
    Author: Wang Nan <wangnan0@huawei.com>
    AuthorDate: Mon, 22 Feb 2016 09:10:36 +0000
    Committer: Arnaldo Carvalho de Melo <acme@redhat.com>
    CommitDate: Mon, 22 Feb 2016 13:02:44 -0300

    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>
    ---
    tools/perf/tests/bpf.c | 2 +-
    tools/perf/util/parse-events.c | 56 +++++++++++++++++++++++++++++++++++++-----
    tools/perf/util/parse-events.h | 3 ++-
    3 files changed, 53 insertions(+), 8 deletions(-)

    diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c
    index 4aed5cb..199501c 100644
    --- a/tools/perf/tests/bpf.c
    +++ b/tools/perf/tests/bpf.c
    @@ -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;
    diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
    index 6e2f203..4c19d5e 100644
    --- a/tools/perf/util/parse-events.c
    +++ b/tools/perf/util/parse-events.c
    @@ -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
    diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
    index e445622..67e4930 100644
    --- a/tools/perf/util/parse-events.h
    +++ b/tools/perf/util/parse-events.h
    @@ -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,
    \
     
     \ /
      Last update: 2016-02-25 08:01    [W:4.217 / U:0.164 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site