Re: [PATCH bpf-next v4 04/13] bpf: Support __arena and __arena__nullable kfunc argument suffixes

"Kumar Kartikeya Dwivedi" <[email protected]>
Newsgroups org.kernel.vger.bpf
Message-ID <[email protected]>
On Thu Aug 6, 2026 at 9:20 PM CEST, Kumar Kartikeya Dwivedi wrote:
> On Thu Aug 6, 2026 at 7:22 PM CEST, Amery Hung wrote:
>> On Wed, Aug 5, 2026 at 2:05 PM Kumar Kartikeya Dwivedi <[email protected]> wrote:
>>>
>>> From: Tejun Heo <[email protected]>
>>>
>>> Passing an arena pointer to a kfunc takes two steps today. There is no
>>> arena pointer argument type, so the pointer crosses the boundary as a
>>> bare scalar, and the kfunc then offsets it by the arena base and casts
>>> it before it can touch the memory. Every such kfunc open-codes the same
>>> translation.
>>>
>>> Add the __arena and __arena__nullable argument suffixes to make this more
>>> convenient. The kfunc declares the parameter by its real pointer type
>>> and dereferences it directly, with the JIT rebasing the value at the
>>> call site, rN = kern_vm_start + (u32)rN. No bounds check is needed: the
>>> u32 offset stays within the guard-padded arena kernel mapping, and a
>>> fault on an unpopulated page recovers through the per-arena scratch
>>> page. A suffixed argument accepts a PTR_TO_ARENA or scalar register,
>>> matching global subprog arena arguments.
>>>
>>> __arena rebases unconditionally, so the kfunc never sees NULL and a
>>> value with zero in the low 32 bits arrives as the arena base.
>>> __arena__nullable preserves NULL for optional arguments by skipping the
>>> rebase when the truncated value, arena offset 0, is zero. Keeping the
>>> plain form NULL-free saves the NULL test on every call.
>>>
>>> The double separator makes the annotations composable:
>>> __arena__nullable also ends in __nullable. Match the composite suffix
>>> first when classifying kfunc arguments and function-model flags so it
>>> retains arena semantics while carrying the nullable flag.
>>
>> Since __arena__nullable will match is_kfunc_arg_arena() case and go
>> through JIT + regno check, and get its PTR_MAYBE_NULL anyway. How
>> about just keep it as __arena_nullable to simplify the patch?
>>
>> 1. No need to introudce is_kfunc_arg_arena_nullable() and changes in
>> is_kfunc_arg_nullable()
>
> For consistency, would you prefer that I don't manually set | PTR_MAYBE_NULL and
> let is_kfunc_arg_nullable() handle that? That would be another way to address
> this.
>
> In some sense, __arena includes __nullable for the purposes of type checking, so
> it might make sense to add it to the predicate that determines NULL-ness, then
> it will acquire PTR_MAYBE_NULL automatically.
>
> We will still drop is_kfunc_arg_arena_nullable() though.
>
> Anyhow, I don't have any strong preference one way or the other, but thought I'd
> float this as an alternative since it appears to fit better, and details are
> hidden the predicates.

This will amount to adding extra OR for __arena prefix match inside
is_kfunc_arg_nullable(), since __nullable should already match on
__arena__nullable.

>
>> 2. is_kfunc_arg_arena() returns btf_param_match_suffix(btf, arg,
>> "__arena_nullable") || btf_param_match_suffix(btf, arg, "__arena");
>>
>
> Yeah, makes sense.
>
>> [...]
>>
>>> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
>>> index b62e77949542..2b7f6f6bbe76 100644
>>> --- a/kernel/bpf/verifier.c
>>> +++ b/kernel/bpf/verifier.c
>>> @@ -10909,9 +10909,16 @@ static bool is_kfunc_arg_refcounted_kptr(const struct btf *btf, const struct btf
>>>         return btf_param_match_suffix(btf, arg, "__refcounted_kptr");
>>>  }
>>>
>>> +static bool is_kfunc_arg_arena_nullable(const struct btf *btf,
>>> +                                       const struct btf_param *arg)
>>> +{
>>> +       return btf_param_match_suffix(btf, arg, "__arena__nullable");
>>> +}
>>> +
>>>  static bool is_kfunc_arg_nullable(const struct btf *btf, const struct btf_param *arg)
>>>  {
>>> -       return btf_param_match_suffix(btf, arg, "__nullable");
>>> +       return !is_kfunc_arg_arena_nullable(btf, arg) &&
>>> +              btf_param_match_suffix(btf, arg, "__nullable");
>>>  }
>>
>> No need for the changes above.
>>
>>>
>>>  static bool is_kfunc_arg_nonown_allowed(const struct btf *btf, const struct btf_param *arg)
>>> @@ -10929,6 +10936,12 @@ static bool is_kfunc_arg_irq_flag(const struct btf *btf, const struct btf_param
>>>         return btf_param_match_suffix(btf, arg, "__irq_flag");
>>>  }
>>>
>>> +static bool is_kfunc_arg_arena(const struct btf *btf, const struct btf_param *arg)
>>> +{
>>> +       return is_kfunc_arg_arena_nullable(btf, arg) ||
>>> +              btf_param_match_suffix(btf, arg, "__arena");
>>
>> return btf_param_match_suffix(btf, arg, "__arena_nullable") ||
>>         btf_param_match_suffix(btf, arg, "__arena");
>>
>
> Ack, I'll adjust this bit.
>
>> [...]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.