Re: [PATCH bpf-next v1 0/8] bpf: magic kernel functions

Alan Maguire
2025-10-30T18:26:47Z

On 30/10/2025 18:14, Eduard Zingerman wrote:
> On Wed, 2025-10-29 at 23:11 -0700, Eduard Zingerman wrote:
>> On Wed, 2025-10-29 at 17:44 -0700, Eduard Zingerman wrote:
>>> On Wed, 2025-10-29 at 12:01 -0700, Ihor Solodrai wrote:
>>>
>>> Do we break compatibility with old pahole versions after this
>>> patch-set? Old paholes won't synthesize the _impl kfuncs, so:
>>> - binary compatibility between new-kernel/old-pahole + old-bpf
>>>   will be broken, as there would be no _impl kfuncs;
>>> - new-kernel/old-pahole + new-bpf won't work either, as kernel will
>>> be
>>>   unable to find non-_impl function names for existing kfuncs.
>>>
>>> [...]
>>
>> Point being, if we are going to break backwards compatibility the
>> following things need an update:
>> - Documentation/process/changes.rst
>> minimal pahole version has to be bumped
>> - scripts/Makefile.btf
>> All the different flags and options for different pahole
>> versions can be dropped.
>>
>> ---
>>
>> On the other hand, I'm not sure this useful but relatively obscure
>> feature grants such a compatibility break. Some time ago Ihor
>> advocated for just having two functions in the kernel, so that BTF
>> will be generated for both. And I think that someone suggested putting
>> the fake function to a discard-able section.
>> This way the whole thing can be done in kernel only.
>> E.g. it will look like so:
>>
>> __bpf_kfunc void btf_foo_impl(struct bpf_prog_aux p__implicit)
>> { /* real impl here */ }
>>
>> __bpf_kfunc_proto void btf_foo(void) {}
>>
>> Assuming that __bpf_kfunc_proto hides all the necessary attributes.
>> Not much boilerplate, and a tad easier to understand where second
>> prototype comes from, no need to read pahole.
>
> Scheme discussed off-list for new functions with __implicit args:
> - kernel source code:
>
> __bpf_kfunc void foo(struct bpf_prog_aux p__implicit)
> BTF_ID_FLAGS(foo, KF_IMPLICIT_ARGS)
>
> - pahole:
> - renames foo to foo_impl
> - adds bpf-side definition for 'foo' w/o implicit args
> vmlinux btf:
>
> __bpf_kfunc void foo_impl(struct bpf_prog_aux p__implicit);
> void foo(void);
>
> - resolve_btfids puts the 'foo' (the one w/o implicit args) id to all
> id lists (no changes needed for this, follows from pahole changes);
> - verifier.c:add_kfunc_call()
> - Sees the id of 'foo' and kfunc flags with KF_IMPLICIT_ARGS
> - Replaces the id with id of 'foo_impl'.
>
> This will break the following scenario:
> - new kfunc is added with __implicit arg
> - kernel is built with old pahole
> - vmlinux.h is generated for such kernel
> - bpf program is compiled against such vmlinux.h
> - attempt to run such program on a new kernel compiled with new pahole
> will fail.
>
> Andrei and Alexei deemed this acceptable.

Okay so bear with me as this is probably a massive over-simplification.
It seems like what we want here is a way to establish a relationship
between the BTF associated with the _impl function and the kfunc-visible
form (without the implicit arguments), right? Once we have that
relationship, it's sort of implicit which are the implicit arguments;
they're the ones the _impl variant has and the non-impl variant doesn't
have. So to me - and again I'm probably missing a lot - the key thing is
to establish that relationship between kfunc and kfunc_impl. Couldn't we
leverage the kernel build machinery around resolve_btf_ids to construct
these pairwise mappings of BTF ids? That way we keep pahole out of the
loop (aside from generating BTF for both variants as usual) and
compatibility issues aren't there as much because resolve_btfids travels
with the kernel, no changes needed for pahole.

I'm guessing the above is missing something though?

Thanks!

Alan