[PATCH] kbuild/btf: Remove broken module relinking exclusion

Petr Pavlu posted 1 patch 2 months ago
scripts/Makefile.modfinal | 10 +---------
1 file changed, 1 insertion(+), 9 deletions(-)
[PATCH] kbuild/btf: Remove broken module relinking exclusion
Posted by Petr Pavlu 2 months ago
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
Re: [PATCH] kbuild/btf: Remove broken module relinking exclusion
Posted by Nathan Chancellor 1 month, 2 weeks ago
On Fri, 10 Apr 2026 15:13:29 +0200, Petr Pavlu wrote:
> kbuild/btf: Remove broken module relinking exclusion

Applied to

  https://git.kernel.org/pub/scm/linux/kernel/git/kbuild/linux.git kbuild-next-unstable

Thanks!

[1/1] kbuild/btf: Remove broken module relinking exclusion
      https://git.kernel.org/kbuild/c/d9ba1abcccdae

Please look out for regression or issue reports or other follow up
comments, as they may result in the patch/series getting dropped or
reverted. Patches applied to an "unstable" branch are accepted pending
wider testing in -next and any post-commit review; they will generally
be moved to the main branch in a week if no issues are found.

Best regards,
-- 
Cheers,
Nathan
Re: [PATCH] kbuild/btf: Remove broken module relinking exclusion
Posted by Ihor Solodrai 2 months ago
On 4/10/26 6:13 AM, 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.

The change makes sense to me.

Acked-by: Ihor Solodrai <ihor.solodrai@linux.dev>

Thank you!

> 
> 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
Re: [PATCH] kbuild/btf: Remove broken module relinking exclusion
Posted by Nathan Chancellor 2 months ago
On Fri, Apr 10, 2026 at 03:13:29PM +0200, 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>

If the BPF folks want to take this since it deals with BTF:

Acked-by: Nathan Chancellor <nathan@kernel.org>

Otherwise, either Nicolas can take this for 7.1 or I will pick it up for
7.2 when 7.1-rc1 is out.

> ---
> 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
>
Re: [PATCH] kbuild/btf: Remove broken module relinking exclusion
Posted by Alexei Starovoitov 2 months ago
On Tue, Apr 14, 2026 at 1:34 PM Nathan Chancellor <nathan@kernel.org> wrote:
>
> On Fri, Apr 10, 2026 at 03:13:29PM +0200, 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>
>
> If the BPF folks want to take this since it deals with BTF:
>
> Acked-by: Nathan Chancellor <nathan@kernel.org>
>
> Otherwise, either Nicolas can take this for 7.1 or I will pick it up for
> 7.2 when 7.1-rc1 is out.

Alan, Ihor,

As resident btf gen experts, Please take a look.
Re: [PATCH] kbuild/btf: Remove broken module relinking exclusion
Posted by Alan Maguire 2 months ago

On 15/04/2026 06:14, Alexei Starovoitov wrote:
> On Tue, Apr 14, 2026 at 1:34 PM Nathan Chancellor <nathan@kernel.org> wrote:
>>
>> On Fri, Apr 10, 2026 at 03:13:29PM +0200, 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>
>>
>> If the BPF folks want to take this since it deals with BTF:
>>
>> Acked-by: Nathan Chancellor <nathan@kernel.org>
>>
>> Otherwise, either Nicolas can take this for 7.1 or I will pick it up for
>> 7.2 when 7.1-rc1 is out.
> 
> Alan, Ihor,
> 
> As resident btf gen experts, Please take a look.

Tried it out with full build, rebuild, module-only (M=) build etc. All work
well so feel free to add

Reviewed-by: Alan Maguire <alan.maguire@oracle.com>
Tested-by: Alan Maguire <alan.maguire@oracle.com>
Re: [PATCH] kbuild/btf: Remove broken module relinking exclusion
Posted by Petr Pavlu 2 months ago
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