* [PATCH] kbuild/btf: Remove broken module relinking exclusion
@ 2026-04-10 13:13 Petr Pavlu
2026-04-13 7:54 ` Petr Pavlu
0 siblings, 1 reply; 2+ messages in thread
From: Petr Pavlu @ 2026-04-10 13:13 UTC (permalink / raw)
To: Nathan Chancellor, Nicolas Schier, Alexei Starovoitov,
Daniel Borkmann, Andrii Nakryiko
Cc: Martin KaFai Lau, Eduard Zingerman, Song Liu, Yonghong Song,
John Fastabend, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
Luis Chamberlain, Daniel Gomez, Sami Tolvanen, Aaron Tomlin,
Ihor Solodrai, Masahiro Yamada, Sasha Levin, linux-kbuild, bpf,
linux-modules, linux-kernel, Petr Pavlu
Commit 5f9ae91f7c0d ("kbuild: Build kernel module BTFs if BTF is enabled
and pahole supports it") in 2020 introduced CONFIG_DEBUG_INFO_BTF_MODULES
to enable generation of split BTF for kernel modules. This change required
the %.ko Makefile rule to additionally depend on vmlinux, which is used as
a base for deduplication. The regular ld_ko_o command executed by the rule
was then modified to be skipped if only vmlinux changes. This was done by
introducing a new if_changed_except command and updating the original call
to '+$(call if_changed_except,ld_ko_o,vmlinux)'.
Later, commit 214c0eea43b2 ("kbuild: add $(objtree)/ prefix to some
in-kernel build artifacts") in 2024 updated the rule's reference to vmlinux
from 'vmlinux' to '$(objtree)/vmlinux'. This accidentally broke the
previous logic to skip relinking modules if only vmlinux changes. The issue
is that '$(objtree)' is typically '.' and GNU Make normalizes the resulting
prerequisite './vmlinux' to just 'vmlinux', while the exclusion logic
retains the raw './vmlinux'. As a result, if_changed_except doesn't
correctly filter out vmlinux. Consequently, with
CONFIG_DEBUG_INFO_BTF_MODULES=y, modules are relinked even if only vmlinux
changes.
It is possible to fix this Makefile issue. However, having the %.ko rule
update the resulting file in place without starting from the original
inputs is rather fragile. The logic is harder to debug if something breaks
during a subsequent .ko update because the old input is lost due to the
overwrite. Additionally, it requires that the BTF processing is idempotent.
For example, sorting id+flags BTF_SET8 pairs in .BTF_ids by resolve_btfids
currently doesn't have this property.
One option is to split the %.ko target into two rules: the first for
partial linking and the second one for generating the BTF data. However,
this approach runs into an issue with requiring additional intermediate
files, which increases the size of the build directory. On my system, when
using a large distribution config with ~5500 modules, the size of the build
directory with debuginfo enabled is already ~25 GB, with .ko files
occupying ~8 GB. Duplicating these .ko files doesn't seem practical.
Measuring the speed of the %.ko processing shows that the link step is
actually relatively fast. It takes about 20% of the overall rule time,
while the BTF processing accounts for 80%. Moreover, skipping the link part
becomes relevant only during local development. In such cases, developers
typically use configs that enable a limited number of modules, so having
the %.ko rule slightly slower doesn't significantly impact the total
rebuild time. This is supported by the fact that no one has complained
about this optimization being broken for the past two years.
Therefore, remove the logic that prevents module relinking when only
vmlinux changes and simplify Makefile.modfinal.
Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
---
My previous attempt to fix this logic can be found at
https://lore.kernel.org/linux-modules/20260402141911.1577711-1-petr.pavlu@suse.com/
---
scripts/Makefile.modfinal | 10 +---------
1 file changed, 1 insertion(+), 9 deletions(-)
diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal
index adcbcde16a07..01a37ec872b9 100644
--- a/scripts/Makefile.modfinal
+++ b/scripts/Makefile.modfinal
@@ -46,17 +46,9 @@ quiet_cmd_btf_ko = BTF [M] $@
$(CONFIG_SHELL) $(srctree)/scripts/gen-btf.sh --btf_base $(objtree)/vmlinux $@; \
fi;
-# Same as newer-prereqs, but allows to exclude specified extra dependencies
-newer_prereqs_except = $(filter-out $(PHONY) $(1),$?)
-
-# Same as if_changed, but allows to exclude specified extra dependencies
-if_changed_except = $(if $(call newer_prereqs_except,$(2))$(cmd-check), \
- $(cmd); \
- printf '%s\n' 'savedcmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:)
-
# Re-generate module BTFs if either module's .ko or vmlinux changed
%.ko: %.o %.mod.o .module-common.o $(objtree)/scripts/module.lds $(and $(CONFIG_DEBUG_INFO_BTF_MODULES),$(KBUILD_BUILTIN),$(objtree)/vmlinux) FORCE
- +$(call if_changed_except,ld_ko_o,$(objtree)/vmlinux)
+ +$(call if_changed,ld_ko_o)
ifdef CONFIG_DEBUG_INFO_BTF_MODULES
+$(if $(newer-prereqs),$(call cmd,btf_ko))
endif
base-commit: 591cd656a1bf5ea94a222af5ef2ee76df029c1d2
--
2.53.0
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH] kbuild/btf: Remove broken module relinking exclusion
2026-04-10 13:13 [PATCH] kbuild/btf: Remove broken module relinking exclusion Petr Pavlu
@ 2026-04-13 7:54 ` Petr Pavlu
0 siblings, 0 replies; 2+ messages in thread
From: Petr Pavlu @ 2026-04-13 7:54 UTC (permalink / raw)
To: Nathan Chancellor, Nicolas Schier, Alexei Starovoitov,
Daniel Borkmann, Andrii Nakryiko
Cc: Martin KaFai Lau, Eduard Zingerman, Song Liu, Yonghong Song,
John Fastabend, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
Luis Chamberlain, Daniel Gomez, Sami Tolvanen, Aaron Tomlin,
Ihor Solodrai, Masahiro Yamada, Sasha Levin, linux-kbuild, bpf,
linux-modules, linux-kernel
On 4/10/26 3:13 PM, Petr Pavlu wrote:
> Commit 5f9ae91f7c0d ("kbuild: Build kernel module BTFs if BTF is enabled
> and pahole supports it") in 2020 introduced CONFIG_DEBUG_INFO_BTF_MODULES
> to enable generation of split BTF for kernel modules. This change required
> the %.ko Makefile rule to additionally depend on vmlinux, which is used as
> a base for deduplication. The regular ld_ko_o command executed by the rule
> was then modified to be skipped if only vmlinux changes. This was done by
> introducing a new if_changed_except command and updating the original call
> to '+$(call if_changed_except,ld_ko_o,vmlinux)'.
>
> Later, commit 214c0eea43b2 ("kbuild: add $(objtree)/ prefix to some
> in-kernel build artifacts") in 2024 updated the rule's reference to vmlinux
> from 'vmlinux' to '$(objtree)/vmlinux'. This accidentally broke the
> previous logic to skip relinking modules if only vmlinux changes. The issue
> is that '$(objtree)' is typically '.' and GNU Make normalizes the resulting
> prerequisite './vmlinux' to just 'vmlinux', while the exclusion logic
> retains the raw './vmlinux'. As a result, if_changed_except doesn't
> correctly filter out vmlinux. Consequently, with
> CONFIG_DEBUG_INFO_BTF_MODULES=y, modules are relinked even if only vmlinux
> changes.
>
> It is possible to fix this Makefile issue. However, having the %.ko rule
> update the resulting file in place without starting from the original
> inputs is rather fragile. The logic is harder to debug if something breaks
> during a subsequent .ko update because the old input is lost due to the
> overwrite. Additionally, it requires that the BTF processing is idempotent.
> For example, sorting id+flags BTF_SET8 pairs in .BTF_ids by resolve_btfids
> currently doesn't have this property.
>
> One option is to split the %.ko target into two rules: the first for
> partial linking and the second one for generating the BTF data. However,
> this approach runs into an issue with requiring additional intermediate
> files, which increases the size of the build directory. On my system, when
> using a large distribution config with ~5500 modules, the size of the build
> directory with debuginfo enabled is already ~25 GB, with .ko files
> occupying ~8 GB. Duplicating these .ko files doesn't seem practical.
>
> Measuring the speed of the %.ko processing shows that the link step is
> actually relatively fast. It takes about 20% of the overall rule time,
> while the BTF processing accounts for 80%. Moreover, skipping the link part
> becomes relevant only during local development. In such cases, developers
> typically use configs that enable a limited number of modules, so having
> the %.ko rule slightly slower doesn't significantly impact the total
> rebuild time. This is supported by the fact that no one has complained
> about this optimization being broken for the past two years.
>
> Therefore, remove the logic that prevents module relinking when only
> vmlinux changes and simplify Makefile.modfinal.
>
> Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
> ---
> My previous attempt to fix this logic can be found at
> https://lore.kernel.org/linux-modules/20260402141911.1577711-1-petr.pavlu@suse.com/
> ---
> scripts/Makefile.modfinal | 10 +---------
> 1 file changed, 1 insertion(+), 9 deletions(-)
>
> diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal
> index adcbcde16a07..01a37ec872b9 100644
> --- a/scripts/Makefile.modfinal
> +++ b/scripts/Makefile.modfinal
> @@ -46,17 +46,9 @@ quiet_cmd_btf_ko = BTF [M] $@
> $(CONFIG_SHELL) $(srctree)/scripts/gen-btf.sh --btf_base $(objtree)/vmlinux $@; \
> fi;
>
> -# Same as newer-prereqs, but allows to exclude specified extra dependencies
> -newer_prereqs_except = $(filter-out $(PHONY) $(1),$?)
> -
> -# Same as if_changed, but allows to exclude specified extra dependencies
> -if_changed_except = $(if $(call newer_prereqs_except,$(2))$(cmd-check), \
> - $(cmd); \
> - printf '%s\n' 'savedcmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:)
> -
> # Re-generate module BTFs if either module's .ko or vmlinux changed
> %.ko: %.o %.mod.o .module-common.o $(objtree)/scripts/module.lds $(and $(CONFIG_DEBUG_INFO_BTF_MODULES),$(KBUILD_BUILTIN),$(objtree)/vmlinux) FORCE
> - +$(call if_changed_except,ld_ko_o,$(objtree)/vmlinux)
> + +$(call if_changed,ld_ko_o)
> ifdef CONFIG_DEBUG_INFO_BTF_MODULES
> +$(if $(newer-prereqs),$(call cmd,btf_ko))
> endif
>
> base-commit: 591cd656a1bf5ea94a222af5ef2ee76df029c1d2
The Sashiko review system makes the following observation [1]:
> Will this result in missing BTF data if the module is rebuilt solely due
> to a command-line change?
>
> Since Kbuild's if_changed executes when either a prerequisite is newer or
> the command line has changed, a command-line-only change (such as modifying
> LDFLAGS_MODULE) will trigger ld_ko_o. This overwrites the .ko file with a
> freshly linked object that lacks a BTF section.
>
> However, because no prerequisite files actually changed, Make's $? variable
> is empty, meaning newer-prereqs is also empty. The subsequent check
> $(if $(newer-prereqs),$(call cmd,btf_ko)) would then evaluate to false and
> skip generating the BTF data entirely.
>
> Could these commands be unified under a single custom Kbuild rule
> (e.g., rule_ld_ko_o) and invoked together using $(call if_changed_rule,ld_ko_o)
> to ensure both linking and BTF generation occur atomically?
I'm aware of this issue. However, it is a separate problem that has
already been present. I'd like to address the exclusion rule first.
[1] https://sashiko.dev/#/patchset/20260410131343.2519532-1-petr.pavlu%40suse.com
-- Petr
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-04-13 7:54 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-10 13:13 [PATCH] kbuild/btf: Remove broken module relinking exclusion Petr Pavlu
2026-04-13 7:54 ` Petr Pavlu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox