This patch adds processing of PERF_BPF_EVENT_PROG_LOAD, which sets proper
DSO type/id/etc of memory regions mapped to BPF programs to
DSO_BINARY_TYPE__BPF_PROG_INFO

Signed-off-by: Song Liu <songliubrav...@fb.com>
---
 tools/perf/util/bpf-event.c | 53 +++++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c
index 536ca95df5f4..9e3eae44c1d5 100644
--- a/tools/perf/util/bpf-event.c
+++ b/tools/perf/util/bpf-event.c
@@ -25,12 +25,65 @@ static int snprintf_hex(char *buf, size_t size, unsigned 
char *data, size_t len)
        return ret;
 }
 
+static int machine__process_bpf_event_load(struct machine *machine,
+                                          union perf_event *event,
+                                          struct perf_sample *sample 
__maybe_unused)
+{
+       struct bpf_prog_info_linear *info_linear;
+       struct bpf_prog_info_node *info_node;
+       struct perf_env *env = machine->env;
+       int id = event->bpf_event.id;
+       unsigned int i;
+
+       /* perf-record, no need to handle bpf-event */
+       if (env == NULL)
+               return 0;
+
+       info_node = perf_env__find_bpf_prog_info(env, id);
+       if (!info_node)
+               return 0;
+       info_linear = info_node->info_linear;
+
+       for (i = 0; i < info_linear->info.nr_jited_ksyms; i++) {
+               u64 *addrs = (u64 *)(info_linear->info.jited_ksyms);
+               u64 addr = addrs[i];
+               struct map *map;
+
+               map = map_groups__find(&machine->kmaps, addr);
+
+               if (map) {
+                       map->dso->binary_type = DSO_BINARY_TYPE__BPF_PROG_INFO;
+                       map->dso->bpf_prog.id = id;
+                       map->dso->bpf_prog.sub_id = i;
+                       map->dso->bpf_prog.env = env;
+               }
+       }
+       return 0;
+}
+
 int machine__process_bpf_event(struct machine *machine __maybe_unused,
                               union perf_event *event,
                               struct perf_sample *sample __maybe_unused)
 {
        if (dump_trace)
                perf_event__fprintf_bpf_event(event, stdout);
+
+       switch (event->bpf_event.type) {
+       case PERF_BPF_EVENT_PROG_LOAD:
+               return machine__process_bpf_event_load(machine, event, sample);
+
+       case PERF_BPF_EVENT_PROG_UNLOAD:
+               /*
+                * Do not free bpf_prog_info and btf of the program here,
+                * as annotation still need them. They will be freed at
+                * the end of the session.
+                */
+               break;
+       default:
+               pr_debug("unexpected bpf_event type of %d\n",
+                        event->bpf_event.type);
+               break;
+       }
        return 0;
 }
 
-- 
2.17.1

Reply via email to