Skip to content

Commit 5f9ae91

Browse files
anakryikoAlexei Starovoitov
authored andcommitted
kbuild: Build kernel module BTFs if BTF is enabled and pahole supports it
Detect if pahole supports split BTF generation, and generate BTF for each selected kernel module, if it does. This is exposed to Makefiles and C code as CONFIG_DEBUG_INFO_BTF_MODULES flag. Kernel module BTF has to be re-generated if either vmlinux's BTF changes or module's .ko changes. To achieve that, I needed a helper similar to if_changed, but that would allow to filter out vmlinux from the list of updated dependencies for .ko building. I've put it next to the only place that uses and needs it, but it might be a better idea to just add it along the other if_changed variants into scripts/Kbuild.include. Each kernel module's BTF deduplication is pretty fast, as it does only incremental BTF deduplication on top of already deduplicated vmlinux BTF. To show the added build time, I've first ran make only just built kernel (to establish the baseline) and then forced only BTF re-generation, without regenerating .ko files. The build was performed with -j60 parallelization on 56-core machine. The final time also includes bzImage building, so it's not a pure BTF overhead. $ time make -j60 ... make -j60 27.65s user 10.96s system 782% cpu 4.933 total $ touch ~/linux-build/default/vmlinux && time make -j60 ... make -j60 123.69s user 27.85s system 1566% cpu 9.675 total So 4.6 seconds real time, with noticeable part spent in compressed vmlinux and bzImage building. To show size savings, I've built my kernel configuration with about 700 kernel modules with full BTF per each kernel module (without deduplicating against vmlinux) and with split BTF against deduplicated vmlinux (approach in this patch). Below are top 10 modules with biggest BTF sizes. And total size of BTF data across all kernel modules. It shows that split BTF "compresses" 115MB down to 5MB total. And the biggest kernel modules get a downsize from 500-570KB down to 200-300KB. FULL BTF ======== $ for f in $(find . -name '*.ko'); do size -A -d $f | grep BTF | awk '{print $2}'; done | awk '{ s += $1 } END { print s }' 115710691 $ for f in $(find . -name '*.ko'); do printf "%s %d\n" $f $(size -A -d $f | grep BTF | awk '{print $2}'); done | sort -nr -k2 | head -n10 ./drivers/gpu/drm/i915/i915.ko 570570 ./drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.ko 520240 ./drivers/gpu/drm/radeon/radeon.ko 503849 ./drivers/infiniband/hw/mlx5/mlx5_ib.ko 491777 ./fs/xfs/xfs.ko 411544 ./drivers/net/ethernet/intel/i40e/i40e.ko 403904 ./drivers/net/ethernet/broadcom/bnx2x/bnx2x.ko 398754 ./drivers/infiniband/core/ib_core.ko 397224 ./fs/cifs/cifs.ko 386249 ./fs/nfsd/nfsd.ko 379738 SPLIT BTF ========= $ for f in $(find . -name '*.ko'); do size -A -d $f | grep BTF | awk '{print $2}'; done | awk '{ s += $1 } END { print s }' 5194047 $ for f in $(find . -name '*.ko'); do printf "%s %d\n" $f $(size -A -d $f | grep BTF | awk '{print $2}'); done | sort -nr -k2 | head -n10 ./drivers/gpu/drm/i915/i915.ko 293206 ./drivers/gpu/drm/radeon/radeon.ko 282103 ./fs/xfs/xfs.ko 222150 ./drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.ko 198503 ./drivers/infiniband/hw/mlx5/mlx5_ib.ko 198356 ./drivers/net/ethernet/broadcom/bnx2x/bnx2x.ko 113444 ./fs/cifs/cifs.ko 109379 ./arch/x86/kvm/kvm.ko 100225 ./drivers/gpu/drm/drm.ko 94827 ./drivers/infiniband/core/ib_core.ko 91188 Signed-off-by: Andrii Nakryiko <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent 5329722 commit 5f9ae91

File tree

2 files changed

+27
-2
lines changed

2 files changed

+27
-2
lines changed

lib/Kconfig.debug

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,15 @@ config DEBUG_INFO_BTF
274274
Turning this on expects presence of pahole tool, which will convert
275275
DWARF type info into equivalent deduplicated BTF type info.
276276

277+
config PAHOLE_HAS_SPLIT_BTF
278+
def_bool $(success, test `$(PAHOLE) --version | sed -E 's/v([0-9]+)\.([0-9]+)/\1\2/'` -ge "119")
279+
280+
config DEBUG_INFO_BTF_MODULES
281+
def_bool y
282+
depends on DEBUG_INFO_BTF && MODULES && PAHOLE_HAS_SPLIT_BTF
283+
help
284+
Generate compact split BTF type information for kernel modules.
285+
277286
config GDB_SCRIPTS
278287
bool "Provide GDB scripts for kernel debugging"
279288
help

scripts/Makefile.modfinal

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
PHONY := __modfinal
77
__modfinal:
88

9+
include include/config/auto.conf
910
include $(srctree)/scripts/Kbuild.include
1011

1112
# for c_flags
@@ -36,8 +37,23 @@ quiet_cmd_ld_ko_o = LD [M] $@
3637
-T scripts/module.lds -o $@ $(filter %.o, $^); \
3738
$(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true)
3839

39-
$(modules): %.ko: %.o %.mod.o scripts/module.lds FORCE
40-
+$(call if_changed,ld_ko_o)
40+
quiet_cmd_btf_ko = BTF [M] $@
41+
cmd_btf_ko = LLVM_OBJCOPY=$(OBJCOPY) $(PAHOLE) -J --btf_base vmlinux $@
42+
43+
# Same as newer-prereqs, but allows to exclude specified extra dependencies
44+
newer_prereqs_except = $(filter-out $(PHONY) $(1),$?)
45+
46+
# Same as if_changed, but allows to exclude specified extra dependencies
47+
if_changed_except = $(if $(call newer_prereqs_except,$(2))$(cmd-check), \
48+
$(cmd); \
49+
printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:)
50+
51+
# Re-generate module BTFs if either module's .ko or vmlinux changed
52+
$(modules): %.ko: %.o %.mod.o scripts/module.lds vmlinux FORCE
53+
+$(call if_changed_except,ld_ko_o,vmlinux)
54+
ifdef CONFIG_DEBUG_INFO_BTF_MODULES
55+
+$(if $(newer-prereqs),$(call cmd,btf_ko))
56+
endif
4157

4258
targets += $(modules) $(modules:.ko=.mod.o)
4359

0 commit comments

Comments
 (0)