Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3ca3877a authored by Song Liu's avatar Song Liu Committed by Arnaldo Carvalho de Melo
Browse files

perf bpf: Process PERF_BPF_EVENT_PROG_LOAD for annotation



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: default avatarSong Liu <songliubraving@fb.com>
Reviewed-by: default avatarJiri Olsa <jolsa@kernel.org>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stanislav Fomichev <sdf@google.com>
Cc: kernel-team@fb.com
Link: http://lkml.kernel.org/r/20190312053051.2690567-14-songliubraving@fb.com


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 9b86d04d
Loading
Loading
Loading
Loading
+54 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
#include "machine.h"
#include "env.h"
#include "session.h"
#include "map.h"

#define ptr_to_u64(ptr)    ((__u64)(unsigned long)(ptr))

@@ -25,12 +26,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;
}