Skip to content

Commit 6091197

Browse files
committed
Merge branch 'Subskeleton support for BPF librariesThread-Topic: [PATCH bpf-next v4 0/5'
Delyan Kratunov says: ==================== In the quest for ever more modularity, a new need has arisen - the ability to access data associated with a BPF library from a corresponding userspace library. The catch is that we don't want the userspace library to know about the structure of the final BPF object that the BPF library is linked into. In pursuit of this modularity, this patch series introduces *subskeletons.* Subskeletons are similar in use and design to skeletons with a couple of differences: 1. The generated storage types do not rely on contiguous storage for the library's variables because they may be interspersed randomly throughout the final BPF object's sections. 2. Subskeletons do not own objects and instead require a loaded bpf_object* to be passed at runtime in order to be initialized. By extension, symbols are resolved at runtime by parsing the final object's BTF. 3. Subskeletons allow access to all global variables, programs, and custom maps. They also expose the internal maps *of the final object*. This allows bpf_var_skeleton objects to contain a bpf_map** instead of a section name. Changes since v3: - Re-add key/value type lookup for legacy user maps (fixing btf test) - Minor cleanups (missed sanitize_identifier call, error messages, formatting) Changes since v2: - Reuse SEC_NAME strict mode flag - Init bpf_map->btf_value_type_id on open for internal maps *and* user BTF maps - Test custom section names (.data.foo) and overlapping kconfig externs between the final object and the library - Minor review comments in gen.c & libbpf.c Changes since v1: - Introduced new strict mode knob for single-routine-in-.text compatibility behavior, which disproportionately affects library objects. bpftool works in 1.0 mode so subskeleton generation doesn't have to worry about this now. - Made bpf_map_btf_value_type_id available earlier and used it wherever applicable. - Refactoring in bpftool gen.c per review comments. - Subskels now use typeof() for array and func proto globals to avoid the need for runtime split btf. - Expanded the subskeleton test to include arrays, custom maps, extern maps, weak symbols, and kconfigs. - selftests/bpf/Makefile now generates a subskel.h for every skel.h it would make. For reference, here is a shortened subskeleton header: #ifndef __TEST_SUBSKELETON_LIB_SUBSKEL_H__ #define __TEST_SUBSKELETON_LIB_SUBSKEL_H__ struct test_subskeleton_lib { struct bpf_object *obj; struct bpf_object_subskeleton *subskel; struct { struct bpf_map *map2; struct bpf_map *map1; struct bpf_map *data; struct bpf_map *rodata; struct bpf_map *bss; struct bpf_map *kconfig; } maps; struct { struct bpf_program *lib_perf_handler; } progs; struct test_subskeleton_lib__data { int *var6; int *var2; int *var5; } data; struct test_subskeleton_lib__rodata { int *var1; } rodata; struct test_subskeleton_lib__bss { struct { int var3_1; __s64 var3_2; } *var3; int *libout1; typeof(int[4]) *var4; typeof(int (*)()) *fn_ptr; } bss; struct test_subskeleton_lib__kconfig { _Bool *CONFIG_BPF_SYSCALL; } kconfig; static inline struct test_subskeleton_lib * test_subskeleton_lib__open(const struct bpf_object *src) { struct test_subskeleton_lib *obj; struct bpf_object_subskeleton *s; int err; ... s = (struct bpf_object_subskeleton *)calloc(1, sizeof(*s)); ... s->var_cnt = 9; ... s->vars[0].name = "var6"; s->vars[0].map = &obj->maps.data; s->vars[0].addr = (void**) &obj->data.var6; ... /* maps */ ... /* programs */ s->prog_cnt = 1; ... err = bpf_object__open_subskeleton(s); ... return obj; } #endif /* __TEST_SUBSKELETON_LIB_SUBSKEL_H__ */ ==================== Signed-off-by: Andrii Nakryiko <[email protected]>
2 parents 5a5c11e + 3cccbaa commit 6091197

File tree

13 files changed

+910
-109
lines changed

13 files changed

+910
-109
lines changed

tools/bpf/bpftool/Documentation/bpftool-gen.rst

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ GEN COMMANDS
2525

2626
| **bpftool** **gen object** *OUTPUT_FILE* *INPUT_FILE* [*INPUT_FILE*...]
2727
| **bpftool** **gen skeleton** *FILE* [**name** *OBJECT_NAME*]
28+
| **bpftool** **gen subskeleton** *FILE* [**name** *OBJECT_NAME*]
2829
| **bpftool** **gen min_core_btf** *INPUT* *OUTPUT* *OBJECT* [*OBJECT*...]
2930
| **bpftool** **gen help**
3031
@@ -150,6 +151,30 @@ DESCRIPTION
150151
(non-read-only) data from userspace, with same simplicity
151152
as for BPF side.
152153

154+
**bpftool gen subskeleton** *FILE*
155+
Generate BPF subskeleton C header file for a given *FILE*.
156+
157+
Subskeletons are similar to skeletons, except they do not own
158+
the corresponding maps, programs, or global variables. They
159+
require that the object file used to generate them is already
160+
loaded into a *bpf_object* by some other means.
161+
162+
This functionality is useful when a library is included into a
163+
larger BPF program. A subskeleton for the library would have
164+
access to all objects and globals defined in it, without
165+
having to know about the larger program.
166+
167+
Consequently, there are only two functions defined
168+
for subskeletons:
169+
170+
- **example__open(bpf_object\*)**
171+
Instantiates a subskeleton from an already opened (but not
172+
necessarily loaded) **bpf_object**.
173+
174+
- **example__destroy()**
175+
Frees the storage for the subskeleton but *does not* unload
176+
any BPF programs or maps.
177+
153178
**bpftool** **gen min_core_btf** *INPUT* *OUTPUT* *OBJECT* [*OBJECT*...]
154179
Generate a minimum BTF file as *OUTPUT*, derived from a given
155180
*INPUT* BTF file, containing all needed BTF types so one, or

tools/bpf/bpftool/bash-completion/bpftool

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1003,13 +1003,25 @@ _bpftool()
10031003
;;
10041004
esac
10051005
;;
1006+
subskeleton)
1007+
case $prev in
1008+
$command)
1009+
_filedir
1010+
return 0
1011+
;;
1012+
*)
1013+
_bpftool_once_attr 'name'
1014+
return 0
1015+
;;
1016+
esac
1017+
;;
10061018
min_core_btf)
10071019
_filedir
10081020
return 0
10091021
;;
10101022
*)
10111023
[[ $prev == $object ]] && \
1012-
COMPREPLY=( $( compgen -W 'object skeleton help min_core_btf' -- "$cur" ) )
1024+
COMPREPLY=( $( compgen -W 'object skeleton subskeleton help min_core_btf' -- "$cur" ) )
10131025
;;
10141026
esac
10151027
;;

0 commit comments

Comments
 (0)