Skip to contentSkip to conversation

perf bpf: Add bpf/stdio.h wrapper to bpf_perf_event_output function

tip:perf/urgent tip-bot for Arnaldo Carvalho de Melo 1 participant 1 message Aug 18, 2018 perf events

lore
Share & tools
lore
#0 lore raw
Commit-ID:  53a5d7b80032fcf48cdc5a6c96c8dc8a120b64ef
Gitweb:     https://git.kernel.org/tip/53a5d7b80032fcf48cdc5a6c96c8dc8a120b64ef
Author:     Arnaldo Carvalho de Melo <[email protected]>
AuthorDate: Mon, 6 Aug 2018 09:15:18 -0300
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Wed, 8 Aug 2018 15:55:55 -0300

perf bpf: Add bpf/stdio.h wrapper to bpf_perf_event_output function

That, together with the map __bpf_output__ that is already handled by 'perf trace' to print that event's contents as strings provides a debugging facility, to show it in use, print a simple string everytime the syscalls:sys_enter_openat() syscall tracepoint is hit:

  # cat tools/perf/examples/bpf/hello.c
  #include <stdio.h>

int syscall_enter(openat)(void *args)

  {
	  puts("Hello, world\n");
	  return 0;

}

  license(GPL);
  #
  # perf trace -e openat,tools/perf/examples/bpf/hello.c cat /etc/passwd > /dev/null
     0.016 (         ): __bpf_stdout__:Hello, world
     0.018 ( 0.010 ms): cat/9079 openat(dfd: CWD, filename: /etc/ld.so.cache, flags: CLOEXEC) = 3
     0.057 (         ): __bpf_stdout__:Hello, world
     0.059 ( 0.011 ms): cat/9079 openat(dfd: CWD, filename: /lib64/libc.so.6, flags: CLOEXEC) = 3
     0.417 (         ): __bpf_stdout__:Hello, world
     0.419 ( 0.009 ms): cat/9079 openat(dfd: CWD, filename: /etc/passwd) = 3
  #

This is part of an ongoing experimentation on making eBPF scripts as consumed by perf to be as concise as possible and using familiar concepts such as stdio.h functions, that end up just wrapping the existing BPF functions, trying to hide as much boilerplate as possible while using just conventions and C preprocessor tricks.

---
 tools/perf/examples/bpf/hello.c |  9 +++++++++
 tools/perf/include/bpf/stdio.h  | 19 +++++++++++++++++++
 2 files changed, 28 insertions(+)
tools/perf/examples/bpf/hello.c new file +9 -0
new file mode 100644
index 000000000000..cf3c2fdc7f79
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+int syscall_enter(openat)(void *args)
+{
+	puts("Hello, world\n");
+	return 0;
+}
+
+license(GPL);
tools/perf/include/bpf/stdio.h new file +19 -0
new file mode 100644
index 000000000000..2899cb7bfed8
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <bpf.h>
+
+struct bpf_map SEC("maps") __bpf_stdout__ = {
+       .type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
+       .key_size = sizeof(int),
+       .value_size = sizeof(u32),
+       .max_entries = __NR_CPUS__,
+};
+
+static int (*perf_event_output)(void *, struct bpf_map *, int, void *, unsigned long) =
+	(void *)BPF_FUNC_perf_event_output;
+
+#define puts(from) \
+	({ const int __len = sizeof(from); \
+	   char __from[__len] = from; \
+	   perf_event_output(args, &__bpf_stdout__, BPF_F_CURRENT_CPU, \
+			  &__from, __len & (sizeof(from) - 1)); })