[PATCH v2 bpf-next 00/18] Support inline functions in BTF
From: Alan Maguire <hidden>
Date: 2026-09-01 16:58:31
Also in:
bpf
This series adds support to facilitate tracing of inline function sites using BPF Type Format (BTF) information. An excellent overview of the problem and proposed solution presented at LSF/MM/BPF is available at [1]. The aim is to produce a compact representation providing sufficient information to a tracer wishing to instrument an inline site via a kprobe. The challenge to solve is compact representation - my local bpf-next builds show nearly 600,000 inline sites for approximately 100,000 functions. Any BTF representation should utilize deduplication where possible to minimize overheads. The approach used here is to encode a series of inline sites in a BTF DATASEC-like LOCSEC named for the associated section (like ".text", where each entry consists of a <function type id, location prototype id, offset from base address> triple. The function type id is the BTF_KIND_FUNC that was inlined, the location prototype is a BTF_KIND_LOC_PROTO which tells us for each function parameter how it is represented at the site. It is a collection of either type id 0 (parameter not available) or BTF_KIND_LOC_PARAM ids, the latter encoding a register number, a dereference, a constant etc. Finally the offset is relative to the base address, so in the case of the kernel this allows for kASLR, and modules addresses are relative to module base address. Full location parameter information is available for ~78% of inlined functions; in other words all function parameters are expressed via BTF_KIND_LOC_PARAM and can be retrieved. Those remaining have more complex multi-expression encoding or are not available at all. For a vmlinux with 6Mb of BTF in /sys/kernel/btf/vmlinux, I see 10.8Mb of inline information. When delivered as a compressed module, the module size is 3.5Mb (via CONFIG_DEBUG_INFO_BTF_INLINE=m). In this module-delivered mode, /sys/kernel/btf/vmlinux.inline will be zero-sized until it is opened, at which point the module is requested so the user experience is identical to when inline info is derived from vmlinux itself, but we save the allocation associated with live inline representation. This series is rather large, and ideally we would split it into basic inline support in kernel/libbpf/bpftool and associated tests (patches 1-11) and delivery of inline info (patches 12-18). This would allow us to land the pahole support once the libbpf interfaces become available, though it will work in its absence. The pahole code is still being tested but is available at [2]. Patch 1 consists of the UAPI changes and associated basic support for KIND_LOC[SEC|PARAM|PROTO]. Patch 2 wires in libbpf support to handle these, including in dedup, field iteration and so on. LOCSEC does not dedup since each entry has a unique offset, but LOC_PARAM and LOC_PROTO do. Patch 3 widens BTF permutation to support a transfer mode which allows us to move a subset of types to a newly-created split BTF. This will allow resolve_btfids to take a pahole-generated BTF object (consisting of usual BTF plus inline info) and separate out the inline-relevant components into a new .BTF.inline section. This is an approach in line with other resolve_btfids changes which prepare more generic BTF for the needs of the kernel. Patches 4-8 provide tests for all of this. Patches 9-11 add bpftool support to handle multi-split BTF for inline info and to display location info. Patch 12 adds resolve_btfids support to split out inline info with the aim that any functions that are exclusively needed for inline sites wind up in the inline BTF; this is a good test to see if a function is likely fully inlined. Similarly any LOCSEC references < start BTF id of the inline BTF suggest partially inlined functions. See the patch for the nuances. resolve_btfids takes as input BTF consisting of the usual vmlinux BTF objects and inline-related ones; its role is to create a split BTF where we move the inline-related pieces out so that /sys/kernel/btf/vmlinux (or module equivalent) is the same as before and does not pay the cost of inline representations. This approach is different to how it was done in the RFC because the model of applying kernel customizations in resolve_btfids did not exist to the same degree then. In the RFC approach, pahole delivered already-split BTF and we relocated it, but since the base BTF it is built on now is transformed significantly (added/changed types, sorting, dedup) it is not feasible to track id changes across all of these operations. As such we view splitting the inline info out as another kernel-specific customization. Patches 13-16 add support to the kbuild infrastructure and /sys/kernel/btf representations for inline data. We can choose to deliver vmlinux inline info via a module (since it is ~10Mb that makes sense) but there are some issues in getting that module to load when /sys/kernel/btf/vmlinux.inline is accessed that are described in patch 15). Patch 16 handles relocation of distilled base BTF for out-of-tree modules, ensuring that relocation works across module and module inline info. The painful part here is that we need to relocate ids in the inline info, which requires multi-split BTF support. Happily that is not a big change. Finally tests in patches 17, 18 cover sysfs representation and we introduce an inline site to bpf_testmod and ensure its representation makes sense. Changes since RFC [3]: - Support for distilled base BTF - Support for BTF_INLINE=m on-demand loading - Reworked inline support to handle new resolve_btfids model - .BTF.inline sections host FUNCs/FUNC_PROTOs/strings that are needed for inline info only, avoiding polluting standard vmlinux/module BTFs [1] https://lwn.net/Articles/1083985/ [2] https://github.com/alan-maguire/dwarves/tree/pahole-next-btf-inline-v2-testing [3] https://lore.kernel.org/bpf/20251008173512.731801-1-alan.maguire@oracle.com/ (local) Alan Maguire (18): btf: Extend UAPI to support BTF location (inline site) info libbpf: Add support for BTF kinds LOC[_PARAM|_PROTO|SEC] libbpf: Support moving permuted BTF types into split BTF selftests/bpf: Test helper support for BTF_KIND_LOC[_PARAM|_PROTO|SEC] selftests/bpf: Add LOC_PARAM, LOC_PROTO, LOCSEC to field iter tests selftests/bpf: Add LOC_PARAM, LOC_PROTO, LOCSEC to dedup split tests selftests/bpf: BTF distill tests to ensure LOC[_PARAM|_PROTO] add to split BTF selftests/bpf: Validate that btf__permute transfer works bpftool: Handle multi-split BTF by supporting multiple base BTFs bpftool: Document support for multi-split BTF bpftool: Add ability to dump LOC_PARAM, LOC_PROTO and LOCSEC resolve_btfids: Extract inline BTF kbuild: Add support for BTF inline information btf: Make vmlinux, module inline info available in /sys/kernel/btf btf: Support CONFIG_DEBUG_INFO_BTF_INLINE=m btf: Relocate inline BTF for modules with distilled base BTF selftests/bpf: Test BTF sysfs inline representations selftests/bpf: Add a test verifying inline information Makefile | 1 + include/asm-generic/vmlinux.lds.h | 11 + include/linux/btf.h | 23 +- include/linux/module.h | 4 + include/uapi/linux/btf.h | 65 +- kernel/bpf/Makefile | 1 + kernel/bpf/btf.c | 686 ++++++++++++++++-- kernel/bpf/btf_vmlinux_inline.c | 37 + kernel/module/main.c | 4 + lib/Kconfig.debug | 18 + scripts/Makefile.btf | 7 + scripts/gen-btf.sh | 33 +- .../bpf/bpftool/Documentation/bpftool-btf.rst | 7 +- tools/bpf/bpftool/btf.c | 85 +++ tools/bpf/bpftool/main.c | 3 +- tools/bpf/resolve_btfids/main.c | 336 ++++++++- tools/include/uapi/linux/btf.h | 65 +- tools/lib/bpf/btf.c | 659 ++++++++++++++++- tools/lib/bpf/btf.h | 66 +- tools/lib/bpf/btf_dump.c | 9 + tools/lib/bpf/btf_iter.c | 22 + tools/lib/bpf/btf_relocate.c | 7 +- tools/lib/bpf/libbpf.map | 6 + tools/lib/bpf/libbpf_internal.h | 5 +- tools/testing/selftests/bpf/btf_helpers.c | 36 +- .../bpf/prog_tests/btf_dedup_split.c | 109 +++ .../selftests/bpf/prog_tests/btf_distill.c | 76 ++ .../selftests/bpf/prog_tests/btf_field_iter.c | 31 +- .../selftests/bpf/prog_tests/btf_inline.c | 110 +++ .../selftests/bpf/prog_tests/btf_permute.c | 128 ++++ .../selftests/bpf/prog_tests/btf_sysfs.c | 74 ++ tools/testing/selftests/bpf/test_btf.h | 16 + .../selftests/bpf/test_kmods/bpf_testmod.c | 2 +- tools/testing/selftests/bpf/trace_helpers.c | 20 + tools/testing/selftests/bpf/trace_helpers.h | 1 + 35 files changed, 2636 insertions(+), 127 deletions(-) create mode 100644 kernel/bpf/btf_vmlinux_inline.c create mode 100644 tools/testing/selftests/bpf/prog_tests/btf_inline.c -- 2.43.5