History

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

Andrii Nakryiko committed 6 years ago

Commit 5f9ae911 parent 53297222 files · +27 −2Browse files

Unified · Split

2 files
  1. lib/Kconfig.debug +9 −0
  2. scripts/Makefile.modfinal +18 −2
lib/Kconfig.debug+9−0
@@ -274,6 +274,15 @@ config DEBUG_INFO_BTF · 273 unmodified lines
274 Turning this on expects presence of pahole tool, which will convert274 Turning this on expects presence of pahole tool, which will convert
275 DWARF type info into equivalent deduplicated BTF type info.275 DWARF type info into equivalent deduplicated BTF type info.
276 276
277config PAHOLE_HAS_SPLIT_BTF
278 def_bool $(success, test `$(PAHOLE) --version | sed -E 's/v([0-9]+)\.([0-9]+)/\1\2/'` -ge "119")
279
280config 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
277config GDB_SCRIPTS286config GDB_SCRIPTS
278 bool "Provide GDB scripts for kernel debugging"287 bool "Provide GDB scripts for kernel debugging"
279 help288 help
scripts/Makefile.modfinal+18−2
@@ -6,6 +6,7 @@ · 5 unmodified lines
6PHONY := __modfinal6PHONY := __modfinal
7__modfinal:7__modfinal:
8 8
9include include/config/auto.conf
9include $(srctree)/scripts/Kbuild.include10include $(srctree)/scripts/Kbuild.include
10 11
11# for c_flags12# for c_flags
@@ -36,8 +37,23 @@ quiet_cmd_ld_ko_o = LD [M] $@ · 24 unmodified lines
36 -T scripts/module.lds -o $@ $(filter %.o, $^); \37 -T scripts/module.lds -o $@ $(filter %.o, $^); \
37 $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true)38 $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true)
38 39
39$(modules): %.ko: %.o %.mod.o scripts/module.lds FORCE40quiet_cmd_btf_ko = BTF [M] $@
40 +$(call if_changed,ld_ko_o)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
44newer_prereqs_except = $(filter-out $(PHONY) $(1),$?)
45
46# Same as if_changed, but allows to exclude specified extra dependencies
47if_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)
54ifdef CONFIG_DEBUG_INFO_BTF_MODULES
55 +$(if $(newer-prereqs),$(call cmd,btf_ko))
56endif
41 57
42targets += $(modules) $(modules:.ko=.mod.o)58targets += $(modules) $(modules:.ko=.mod.o)
43 59