On Mon, Feb 25, 2019 at 04:20:10PM -0800, Song Liu wrote: > bpf_prog_info contains information necessary to annotate bpf programs. > This patch saves bpf_prog_info for bpf programs loaded in the system. > > Signed-off-by: Song Liu <songliubrav...@fb.com> > --- > tools/perf/util/bpf-event.c | 32 +++++++++++++- > tools/perf/util/bpf-event.h | 7 ++- > tools/perf/util/env.c | 85 +++++++++++++++++++++++++++++++++++++ > tools/perf/util/env.h | 17 ++++++++ > 4 files changed, 139 insertions(+), 2 deletions(-) > > diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c > index ff7ee149ec46..ce81b2c43a51 100644 > --- a/tools/perf/util/bpf-event.c > +++ b/tools/perf/util/bpf-event.c > @@ -10,6 +10,7 @@ > #include "debug.h" > #include "symbol.h" > #include "machine.h" > +#include "env.h" > #include "session.h" > > #define ptr_to_u64(ptr) ((__u64)(unsigned long)(ptr)) > @@ -54,17 +55,28 @@ static int perf_event__synthesize_one_bpf_prog(struct > perf_session *session, > struct bpf_event *bpf_event = &event->bpf_event; > struct bpf_prog_info_linear *info_linear; > struct perf_tool *tool = session->tool; > + struct bpf_prog_info_node *info_node; > struct bpf_prog_info *info; > struct btf *btf = NULL; > bool has_btf = false; > + struct perf_env *env; > u32 sub_prog_cnt, i; > int err = 0; > u64 arrays; > > + /* > + * for perf-record and perf-report use header.env; > + * otherwise, use global perf_env. > + */ > + env = session->data ? &session->header.env : &perf_env; > + > arrays = 1UL << BPF_PROG_INFO_JITED_KSYMS; > arrays |= 1UL << BPF_PROG_INFO_JITED_FUNC_LENS; > arrays |= 1UL << BPF_PROG_INFO_FUNC_INFO; > arrays |= 1UL << BPF_PROG_INFO_PROG_TAGS; > + arrays |= 1UL << BPF_PROG_INFO_JITED_INSNS; > + arrays |= 1UL << BPF_PROG_INFO_LINE_INFO; > + arrays |= 1UL << BPF_PROG_INFO_JITED_LINE_INFO; > > info_linear = bpf_program__get_prog_info_linear(fd, arrays); > if (IS_ERR_OR_NULL(info_linear)) { > @@ -153,8 +165,8 @@ static int perf_event__synthesize_one_bpf_prog(struct > perf_session *session, > machine, process); > } > > - /* Synthesize PERF_RECORD_BPF_EVENT */ > if (opts->bpf_event) { > + /* Synthesize PERF_RECORD_BPF_EVENT */ > *bpf_event = (struct bpf_event){ > .header = { > .type = PERF_RECORD_BPF_EVENT, > @@ -167,6 +179,24 @@ static int perf_event__synthesize_one_bpf_prog(struct > perf_session *session, > memcpy(bpf_event->tag, info->tag, BPF_TAG_SIZE); > memset((void *)event + event->header.size, 0, > machine->id_hdr_size); > event->header.size += machine->id_hdr_size; > + > + /* save bpf_prog_info to env */
why do we save this to perf_env in here? we just synthesize the same data as event, so report and top will read it and fill perf_env again, right? could you please explain the whole flow of the bpf events and its respective data in perf_env and put it into the changelog > + info_node = malloc(sizeof(struct bpf_prog_info_node)); > + > + /* > + * Do not bail out for !info_node, as we still want to > + * call perf_tool__process_synth_event() well, we are out of memory, so I dont think perf_tool__process_synth_event will get too far.. also the perf_env data would be inconsistent with what you store as event.. how can that work? thanks, jirka > + */ > + if (info_node) { > + info_node->info_linear = info_linear; > + perf_env__insert_bpf_prog_info(env, info_node); > + info_linear = NULL; > + } > + SNIP