Re: [PATCH bpf-next v1 0/4] resolve_btfids: Support for BTF modifications

From: Alan Maguire

Date: Tue Dec 02 2025 - 07:57:14 EST


On 26/11/2025 19:01, Ihor Solodrai wrote:
> On 11/26/25 4:36 AM, Alan Maguire wrote:
>> On 26/11/2025 01:26, Ihor Solodrai wrote:
>>> This series changes resolve_btfids and kernel build scripts to enable
>>> BTF transformations in resolve_btfids. Main motivation for enhancing
>>> resolve_btfids is to reduce dependency of the kernel build on pahole
>>> capabilities [1] and enable BTF features and optimizations [2][3]
>>> particular to the kernel.
>>>
>>> Patches #1-#3 in the series are non-functional refactoring in
>>> resolve_btfids. The last patch (#4) makes significant changes in
>>> resolve_btfids and introduces scripts/gen-btf.sh. Implementation
>>> changes are described in detail in the patch description.
>>>
>>> One RFC item in this patchset is the --distilled_base [4] handling.
>>> Before this patchset .BTF.base was generated and added to target
>>> binary by pahole, based on these conditions [5]:
>>> * pahole version >=1.28
>>> * the kernel module is out-of-tree (KBUILD_EXTMOD)
>>>
>>> Since BTF finalization is now done by resolve_btfids, it requires
>>> btf__distill_base() to happen there. However, in my opinion, it is
>>> unnecessary to add and pass through a --distilled_base flag for
>>> resolve_btfids.
>>>
>> hi Ihor,
>>
>> Can you say more about what constitutes BTF finalization and why BTF
>> distillation prior to finalization (i.e. in pahole) isn't workable? Is
>> it the concern that we eliminate types due to filtering, or is it a
>> problem with sorting/tracking type ids? Are there operations we
>> do/anticipate that make prior distillation infeasbile? Thanks!
>
> Hi Alan,
>
> That's a good question. AFAIU the distillation should be done on the
> final BTF, after all the transformations (sorting, adding/removing BTF
> types) have been applied. At least this way we can be sure that the
> distilled base is valid.
>
> We certainly want BTF generation process to be the same for modules
> and the kernel, which means that BTF modifications in resolve_btfids
> have to be applied to module BTF also.
>
> So the question is whether btf2btf will be safe to do *after*
> distillation, and that of course depends on the specifics.
>
> Let's say pahole generated BTF for a module and a distilled base. If
> later some types are removed from module BTF, or a new type is added
> (that might refer to a type absent in distilled base), is the btf/base
> pair still valid?
>
> My intuition is that it is more reliable to distill the final-final
> BTF, and so with resolve_btfids taking over kernel BTF finalization it
> makes sense to do it there. Otherwise we may be upfront limiting
> ourselves in how module BTF can be changed in resolve_btfids.
>
> What are the reasons to keep distillation in pahole? It's a simple
> libbpf API call after all. Anything I might be missing?
>
>

Nope, I think doing distillation as the final step makes sense to me
too since we get a clearer picture of the types that the module references.
My only reservation was applying distillation to every module (rather
than just out-of-tree builds) but it sounds like that's not needed from below.

>>
>>> Logically, any split BTF referring to kernel BTF is not very useful
>>> without the .BTF.base, which is why the feature was developed in the
>>> first place. Therefore it makes sense to always emit .BTF.base for all
>>> modules, unconditionally. This is implemented in the series.
>>>
>>> However it might be argued that .BTF.base is redundant for in-tree
>>> modules: it takes space the module ELF and triggers unnecessary
>>> btf__relocate() call on load [6]. It can be avoided by special-casing
>>> in-tree module handling in resolve_btfids either with a flag or by
>>> checking env variables. The trade-off is slight performance impact vs
>>> code complexity.
>>>
>>
>> I would say avoid distillation for in-tree modules if possible, as it
>> imposes runtime costs in relocation/type renumbering on module load. For
>> large modules (amdgpu take a bow) that could be non-trivial time-wise.
>> IMO the build-time costs/complexities are worth paying to avoid a
>> runtime tax on module load.
>
> Acked. I still would like to avoid passing flags around if possible.
>
> Is it reasonable to simply check for KBUILD_EXTMOD env var from
> withing resolve_btfids? Any drawbacks to that?
>

None that I can think of; sounds like a good approach to me and is basically
equivalent to what we do now. I'll take a look at v2. Thanks!

Alan

> Thanks.
>
>
>>
>>> [1] https://lore.kernel.org/dwarves/ba1650aa-fafd-49a8-bea4-bdddee7c38c9@xxxxxxxxx/
>>> [2] https://lore.kernel.org/bpf/20251029190113.3323406-1-ihor.solodrai@xxxxxxxxx/
>>> [3] https://lore.kernel.org/bpf/20251119031531.1817099-1-dolinux.peng@xxxxxxxxx/
>>> [4] https://docs.kernel.org/bpf/btf.html#btf-base-section
>>> [5] https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git/tree/scripts/Makefile.btf#n29
>>> [6] https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git/tree/kernel/bpf/btf.c#n6358
>>>
>>> Ihor Solodrai (4):
>>> resolve_btfids: rename object btf field to btf_path
>>> resolve_btfids: factor out load_btf()
>>> resolve_btfids: introduce enum btf_id_kind
>>> resolve_btfids: change in-place update with raw binary output
>>>
>>> MAINTAINERS | 1 +
>>> scripts/Makefile.modfinal | 5 +-
>>> scripts/gen-btf.sh | 166 ++++++++++++++++++++++
>>> scripts/link-vmlinux.sh | 42 +-----
>>> tools/bpf/resolve_btfids/main.c | 234 +++++++++++++++++++++++---------
>>> 5 files changed, 348 insertions(+), 100 deletions(-)
>>> create mode 100755 scripts/gen-btf.sh
>>>
>>
>