diff options
| -rw-r--r-- | tools/perf/util/bpf-event.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c index a4fc52b4ffae..852e960692cb 100644 --- a/tools/perf/util/bpf-event.c +++ b/tools/perf/util/bpf-event.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include "machine.h" | 12 | #include "machine.h" |
| 13 | #include "env.h" | 13 | #include "env.h" |
| 14 | #include "session.h" | 14 | #include "session.h" |
| 15 | #include "map.h" | ||
| 15 | 16 | ||
| 16 | #define ptr_to_u64(ptr) ((__u64)(unsigned long)(ptr)) | 17 | #define ptr_to_u64(ptr) ((__u64)(unsigned long)(ptr)) |
| 17 | 18 | ||
| @@ -25,12 +26,65 @@ static int snprintf_hex(char *buf, size_t size, unsigned char *data, size_t len) | |||
| 25 | return ret; | 26 | return ret; |
| 26 | } | 27 | } |
| 27 | 28 | ||
| 29 | static int machine__process_bpf_event_load(struct machine *machine, | ||
| 30 | union perf_event *event, | ||
| 31 | struct perf_sample *sample __maybe_unused) | ||
| 32 | { | ||
| 33 | struct bpf_prog_info_linear *info_linear; | ||
| 34 | struct bpf_prog_info_node *info_node; | ||
| 35 | struct perf_env *env = machine->env; | ||
| 36 | int id = event->bpf_event.id; | ||
| 37 | unsigned int i; | ||
| 38 | |||
| 39 | /* perf-record, no need to handle bpf-event */ | ||
| 40 | if (env == NULL) | ||
| 41 | return 0; | ||
| 42 | |||
| 43 | info_node = perf_env__find_bpf_prog_info(env, id); | ||
| 44 | if (!info_node) | ||
| 45 | return 0; | ||
| 46 | info_linear = info_node->info_linear; | ||
| 47 | |||
| 48 | for (i = 0; i < info_linear->info.nr_jited_ksyms; i++) { | ||
| 49 | u64 *addrs = (u64 *)(info_linear->info.jited_ksyms); | ||
| 50 | u64 addr = addrs[i]; | ||
| 51 | struct map *map; | ||
| 52 | |||
| 53 | map = map_groups__find(&machine->kmaps, addr); | ||
| 54 | |||
| 55 | if (map) { | ||
| 56 | map->dso->binary_type = DSO_BINARY_TYPE__BPF_PROG_INFO; | ||
| 57 | map->dso->bpf_prog.id = id; | ||
| 58 | map->dso->bpf_prog.sub_id = i; | ||
| 59 | map->dso->bpf_prog.env = env; | ||
| 60 | } | ||
| 61 | } | ||
| 62 | return 0; | ||
| 63 | } | ||
| 64 | |||
| 28 | int machine__process_bpf_event(struct machine *machine __maybe_unused, | 65 | int machine__process_bpf_event(struct machine *machine __maybe_unused, |
| 29 | union perf_event *event, | 66 | union perf_event *event, |
| 30 | struct perf_sample *sample __maybe_unused) | 67 | struct perf_sample *sample __maybe_unused) |
| 31 | { | 68 | { |
| 32 | if (dump_trace) | 69 | if (dump_trace) |
| 33 | perf_event__fprintf_bpf_event(event, stdout); | 70 | perf_event__fprintf_bpf_event(event, stdout); |
| 71 | |||
| 72 | switch (event->bpf_event.type) { | ||
| 73 | case PERF_BPF_EVENT_PROG_LOAD: | ||
| 74 | return machine__process_bpf_event_load(machine, event, sample); | ||
| 75 | |||
| 76 | case PERF_BPF_EVENT_PROG_UNLOAD: | ||
| 77 | /* | ||
| 78 | * Do not free bpf_prog_info and btf of the program here, | ||
| 79 | * as annotation still need them. They will be freed at | ||
| 80 | * the end of the session. | ||
| 81 | */ | ||
| 82 | break; | ||
| 83 | default: | ||
| 84 | pr_debug("unexpected bpf_event type of %d\n", | ||
| 85 | event->bpf_event.type); | ||
| 86 | break; | ||
| 87 | } | ||
| 34 | return 0; | 88 | return 0; |
| 35 | } | 89 | } |
| 36 | 90 | ||
