[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20191204070015.3523523-1-andriin@fb.com>
Date: Tue, 3 Dec 2019 22:59:59 -0800
From: Andrii Nakryiko <andriin@...com>
To: <bpf@...r.kernel.org>, <netdev@...r.kernel.org>, <ast@...com>,
<daniel@...earbox.net>
CC: <andrii.nakryiko@...il.com>, <kernel-team@...com>,
Andrii Nakryiko <andriin@...com>
Subject: [RFC PATCH bpf-next 00/16] Add code-generated BPF object skeleton support
This patch set introduces an alternative and complimentary to existing libbpf
API interface for working with BPF objects, maps, programs, and global data
from userspace side. This approach is relying on code generation. bpftool
produces a struct (a.k.a. skeleton) tailored and specific to provided BPF
object file. It includes hard-coded fields and data structures for every map,
program, link, and global data present.
Altogether this approach significantly reduces amount of userspace boilerplate
code required to open, load, attach, and work with BPF objects. It improves
attach/detach story, by providing pre-allocated space for bpf_links, and
ensuring they are properly detached on shutdown. It allows to do away with by
name/title lookups of maps and programs, because libbpf's skeleton API, in
conjunction with generated code from bpftool, is filling in hard-coded fields
with actual pointers to corresponding struct bpf_map/bpf_program/bpf_link.
Also, thanks to BPF array mmap() support, working with global data (variables)
from userspace is now as natural as it is from BPF side: each variable is just
a struct field inside skeleton struct. Furthermore, this allows to have
a natural way for userspace to pre-initialize global data (including
previously impossible to initialize .rodata) by just assigning values to the
same per-variable fields. Libbpf will carefully take into account this
initialization image, will use it to pre-populate BPF maps at creation time,
and will re-mmap() BPF map's contents at exactly the same userspace memory
address such that it can continue working with all the same pointers without
any interruptions. If kernel doesn't support mmap(), global data will still be
successfully initialized, but after map creation global data structures inside
skeleton will be NULL-ed out. This allows userspace application to gracefully
handle lack of mmap() support, if necessary.
As a demonstration of BPF CO-RE, libbpf tracing APIs, and skeleton approach
working together, runqslower tool (originally BCC-based and distributed along
with BCC) is added under samples directory. It's a complete tool with 100%
feature parity with its BCC-based counterpart. But it doesn't require neither
Python, nor Clang/LLVM runtime. It's pre-compiled and can be distributed to
target machine in a compact binary form.
A bunch of selftests are also converted to using skeletons, demonstrating
significant simplification of userspace part of test and reduction in amount
of code necessary.
Andrii Nakryiko (16):
libbpf: don't require root for bpf_object__open()
libbpf: add generic bpf_program__attach()
libbpf: move non-public APIs from libbpf.h to libbpf_internal.h
libbpf: add BPF_EMBED_OBJ macro for embedding BPF .o files
libbpf: expose field/var declaration emitting API internally
libbpf: expose BPF program's function name
libbpf: refactor global data map initialization
libbpf: postpone BTF ID finding for TRACING programs to load phase
libbpf: reduce log level of supported section names dump
libbpf: add experimental BPF object skeleton support
bpftool: add skeleton codegen command
libbpf/samples: add runqslower sample to libbpf samples
selftests/bpf: add BPF skeletons selftests and convert attach_probe.c
selftests/bpf: convert few more selftest to skeletons
selftests/bpf: add test validating data section to struct convertion
layout
bpftool: add `gen skeleton` BASH completions
tools/bpf/bpftool/bash-completion/bpftool | 11 +
tools/bpf/bpftool/gen.c | 482 +++++++++++++++
tools/bpf/bpftool/main.c | 3 +-
tools/bpf/bpftool/main.h | 1 +
tools/bpf/bpftool/net.c | 1 +
tools/lib/bpf/btf_dump.c | 61 +-
tools/lib/bpf/libbpf.c | 583 ++++++++++++++----
tools/lib/bpf/libbpf.h | 63 +-
tools/lib/bpf/libbpf.map | 7 +
tools/lib/bpf/libbpf_internal.h | 63 ++
tools/lib/bpf/samples/runqslower/.gitignore | 2 +
tools/lib/bpf/samples/runqslower/Makefile | 50 ++
.../bpf/samples/runqslower/runqslower.bpf.c | 105 ++++
tools/lib/bpf/samples/runqslower/runqslower.c | 189 ++++++
tools/lib/bpf/samples/runqslower/runqslower.h | 13 +
tools/testing/selftests/bpf/.gitignore | 2 +
tools/testing/selftests/bpf/Makefile | 36 +-
.../selftests/bpf/prog_tests/attach_probe.c | 154 +----
.../selftests/bpf/prog_tests/fentry_fexit.c | 105 ++--
.../selftests/bpf/prog_tests/fentry_test.c | 72 +--
tools/testing/selftests/bpf/prog_tests/mmap.c | 58 +-
.../selftests/bpf/prog_tests/probe_user.c | 6 +-
.../selftests/bpf/prog_tests/rdonly_maps.c | 11 +-
.../selftests/bpf/prog_tests/skeleton.c | 47 ++
.../bpf/prog_tests/stacktrace_build_id.c | 79 +--
.../bpf/prog_tests/stacktrace_build_id_nmi.c | 84 +--
.../selftests/bpf/progs/test_attach_probe.c | 34 +-
.../selftests/bpf/progs/test_skeleton.c | 36 ++
28 files changed, 1759 insertions(+), 599 deletions(-)
create mode 100644 tools/bpf/bpftool/gen.c
create mode 100644 tools/lib/bpf/samples/runqslower/.gitignore
create mode 100644 tools/lib/bpf/samples/runqslower/Makefile
create mode 100644 tools/lib/bpf/samples/runqslower/runqslower.bpf.c
create mode 100644 tools/lib/bpf/samples/runqslower/runqslower.c
create mode 100644 tools/lib/bpf/samples/runqslower/runqslower.h
create mode 100644 tools/testing/selftests/bpf/prog_tests/skeleton.c
create mode 100644 tools/testing/selftests/bpf/progs/test_skeleton.c
--
2.17.1
Powered by blists - more mailing lists