bpf.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jiri Olsa <jolsa@kernel.org>
To: Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>
Cc: "Arnaldo Carvalho de Melo" <acme@redhat.com>,
	"Song Liu" <songliubraving@fb.com>,
	netdev@vger.kernel.org, bpf@vger.kernel.org,
	"Andrii Nakryiko" <andriin@fb.com>, "Yonghong Song" <yhs@fb.com>,
	"Martin KaFai Lau" <kafai@fb.com>,
	"Jakub Kicinski" <kuba@kernel.org>,
	"David Miller" <davem@redhat.com>,
	"Björn Töpel" <bjorn.topel@intel.com>,
	"John Fastabend" <john.fastabend@gmail.com>,
	"Jesper Dangaard Brouer" <hawk@kernel.org>,
	"Song Liu" <song@kernel.org>
Subject: [PATCH 13/15] perf tools: Synthesize bpf_trampoline/dispatcher ksymbol event
Date: Mon,  2 Mar 2020 15:31:52 +0100	[thread overview]
Message-ID: <20200302143154.258569-14-jolsa@kernel.org> (raw)
In-Reply-To: <20200302143154.258569-1-jolsa@kernel.org>

Synthesize bpf images (trampolines/dispatchers) on start,
as ksymbol events from /proc/kallsyms. Having this perf
can recognize samples from those images and perf report
and top shows them correctly.

The rest of the ksymbol handling is already in place from
for the bpf programs monitoring, so only the initial state
was needed.

perf report output:

  # Overhead  Command     Shared Object                  Symbol

    12.37%  test_progs  [kernel.vmlinux]                 [k] entry_SYSCALL_64
    11.80%  test_progs  [kernel.vmlinux]                 [k] syscall_return_via_sysret
     9.63%  test_progs  bpf_prog_bcf7977d3b93787c_prog2  [k] bpf_prog_bcf7977d3b93787c_prog2
     6.90%  test_progs  bpf_trampoline_24456             [k] bpf_trampoline_24456
     6.36%  test_progs  [kernel.vmlinux]                 [k] memcpy_erms

Acked-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Acked-by: Song Liu <songliubraving@fb.com>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/bpf-event.c | 98 +++++++++++++++++++++++++++++++++++++
 1 file changed, 98 insertions(+)

diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c
index a3207d900339..120ec547ae75 100644
--- a/tools/perf/util/bpf-event.c
+++ b/tools/perf/util/bpf-event.c
@@ -6,6 +6,9 @@
 #include <bpf/libbpf.h>
 #include <linux/btf.h>
 #include <linux/err.h>
+#include <linux/string.h>
+#include <internal/lib.h>
+#include <symbol/kallsyms.h>
 #include "bpf-event.h"
 #include "debug.h"
 #include "dso.h"
@@ -290,11 +293,87 @@ static int perf_event__synthesize_one_bpf_prog(struct perf_session *session,
 	return err ? -1 : 0;
 }
 
+struct kallsyms_parse {
+	union perf_event	*event;
+	perf_event__handler_t	 process;
+	struct machine		*machine;
+	struct perf_tool	*tool;
+};
+
+static int
+process_bpf_image(char *name, u64 addr, struct kallsyms_parse *data)
+{
+	struct machine *machine = data->machine;
+	union perf_event *event = data->event;
+	struct perf_record_ksymbol *ksymbol;
+	u32 size;
+
+	ksymbol = &event->ksymbol;
+
+	/*
+	 * The bpf image (trampoline/dispatcher) size is aligned to
+	 * page, while it starts little bit after the page boundary.
+	 */
+	size = page_size - (addr - PERF_ALIGN(addr, page_size));
+
+	*ksymbol = (struct perf_record_ksymbol) {
+		.header = {
+			.type = PERF_RECORD_KSYMBOL,
+			.size = offsetof(struct perf_record_ksymbol, name),
+		},
+		.addr      = addr,
+		.len       = size,
+		.ksym_type = PERF_RECORD_KSYMBOL_TYPE_BPF,
+		.flags     = 0,
+	};
+
+	strncpy(ksymbol->name, name, KSYM_NAME_LEN);
+	ksymbol->header.size += PERF_ALIGN(strlen(name) + 1, sizeof(u64));
+	memset((void *) event + event->header.size, 0, machine->id_hdr_size);
+	event->header.size += machine->id_hdr_size;
+
+	return perf_tool__process_synth_event(data->tool, event, machine,
+					      data->process);
+}
+
+static int
+kallsyms_process_symbol(void *data, const char *_name,
+			char type __maybe_unused, u64 start)
+{
+	char *module, *name;
+	unsigned long id;
+	int err = 0;
+
+	module = strchr(_name, '\t');
+	if (!module)
+		return 0;
+
+	/* We are going after [bpf] module ... */
+	if (strcmp(module + 1, "[bpf]"))
+		return 0;
+
+	name = memdup(_name, (module - _name) + 1);
+	if (!name)
+		return -ENOMEM;
+
+	name[module - _name] = 0;
+
+	/* .. and only for trampolines and dispatchers */
+	if ((sscanf(name, "bpf_trampoline_%lu", &id) == 1) ||
+	    (sscanf(name, "bpf_dispatcher_%lu", &id) == 1))
+		err = process_bpf_image(name, start, data);
+
+	free(name);
+	return err;
+}
+
 int perf_event__synthesize_bpf_events(struct perf_session *session,
 				      perf_event__handler_t process,
 				      struct machine *machine,
 				      struct record_opts *opts)
 {
+	const char *kallsyms_filename = "/proc/kallsyms";
+	struct kallsyms_parse arg;
 	union perf_event *event;
 	__u32 id = 0;
 	int err;
@@ -303,6 +382,8 @@ int perf_event__synthesize_bpf_events(struct perf_session *session,
 	event = malloc(sizeof(event->bpf) + KSYM_NAME_LEN + machine->id_hdr_size);
 	if (!event)
 		return -1;
+
+	/* Synthesize all the bpf programs in system. */
 	while (true) {
 		err = bpf_prog_get_next_id(id, &id);
 		if (err) {
@@ -335,6 +416,23 @@ int perf_event__synthesize_bpf_events(struct perf_session *session,
 			break;
 		}
 	}
+
+	/* Synthesize all the bpf images - trampolines/dispatchers. */
+	if (symbol_conf.kallsyms_name != NULL)
+		kallsyms_filename = symbol_conf.kallsyms_name;
+
+	arg = (struct kallsyms_parse) {
+		.event   = event,
+		.process = process,
+		.machine = machine,
+		.tool    = session->tool,
+	};
+
+	if (kallsyms__parse(kallsyms_filename, &arg, kallsyms_process_symbol)) {
+		pr_err("%s: failed to synthesize bpf images: %s\n",
+		       __func__, strerror(errno));
+	}
+
 	free(event);
 	return err;
 }
-- 
2.24.1


  parent reply	other threads:[~2020-03-02 14:33 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-02 14:31 [PATCHv4 00/15] bpf: Add trampoline and dispatcher to /proc/kallsyms Jiri Olsa
2020-03-02 14:31 ` [PATCH 01/15] x86/mm: Rename is_kernel_text to __is_kernel_text Jiri Olsa
2020-03-02 14:31 ` [PATCH 02/15] bpf: Add bpf_trampoline_ name prefix for DECLARE_BPF_DISPATCHER Jiri Olsa
2020-03-02 14:31 ` [PATCH 03/15] bpf: Add struct bpf_ksym Jiri Olsa
2020-03-02 14:31 ` [PATCH 04/15] bpf: Add name to " Jiri Olsa
2020-03-02 14:31 ` [PATCH 05/15] bpf: Move lnode list node " Jiri Olsa
2020-03-02 14:31 ` [PATCH 06/15] bpf: Add bpf_ksym_tree tree Jiri Olsa
2020-03-03 18:03   ` Alexei Starovoitov
2020-03-03 20:12     ` Jiri Olsa
2020-03-02 14:31 ` [PATCH 07/15] bpf: Move bpf_tree add/del from bpf_prog_ksym_node_add/del Jiri Olsa
2020-03-02 14:31 ` [PATCH 08/15] bpf: Separate kallsyms add/del functions Jiri Olsa
2020-03-02 14:31 ` [PATCH 09/15] bpf: Add bpf_ksym_add/del functions Jiri Olsa
2020-03-02 14:31 ` [PATCH 10/15] bpf: Rename bpf_tree to bpf_progs_tree Jiri Olsa
2020-03-02 14:31 ` [PATCH 11/15] bpf: Add trampolines to kallsyms Jiri Olsa
2020-03-02 14:31 ` [PATCH 12/15] bpf: Add dispatchers " Jiri Olsa
2020-03-02 14:31 ` Jiri Olsa [this message]
2020-03-02 14:31 ` [PATCH 14/15] perf tools: Set ksymbol dso as loaded on arrival Jiri Olsa
2020-03-02 14:31 ` [PATCH 15/15] perf annotate: Add base support for bpf_image Jiri Olsa
2020-03-12 19:55 [PATCHv5 00/15] bpf: Add trampoline and dispatcher to /proc/kallsyms Jiri Olsa
2020-03-12 19:56 ` [PATCH 13/15] perf tools: Synthesize bpf_trampoline/dispatcher ksymbol event Jiri Olsa
2020-04-06 12:54   ` Arnaldo Carvalho de Melo
2020-04-06 13:00     ` Jiri Olsa

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200302143154.258569-14-jolsa@kernel.org \
    --to=jolsa@kernel.org \
    --cc=acme@redhat.com \
    --cc=andriin@fb.com \
    --cc=ast@kernel.org \
    --cc=bjorn.topel@intel.com \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=davem@redhat.com \
    --cc=hawk@kernel.org \
    --cc=john.fastabend@gmail.com \
    --cc=kafai@fb.com \
    --cc=kuba@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=song@kernel.org \
    --cc=songliubraving@fb.com \
    --cc=yhs@fb.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).