Re: [PATCH bpf-next v2 06/20] bpf: Set BPF_INT_F_DYNPTR_IN_KEY conditionally

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On 2/14/2025 7:56 AM, Alexei Starovoitov wrote:
> On Sat, Jan 25, 2025 at 2:59 AM Hou Tao <houtao@xxxxxxxxxxxxxxx> wrote:
>> From: Hou Tao <houtao1@xxxxxxxxxx>
>>
>> When there is bpf_dynptr field in the map key btf type or the map key
>> btf type is bpf_dyntr, set BPF_INT_F_DYNPTR_IN_KEY in map_flags.
>>
>> Signed-off-by: Hou Tao <houtao1@xxxxxxxxxx>
>> ---
>>  kernel/bpf/syscall.c | 36 ++++++++++++++++++++++++++++++++++++
>>  1 file changed, 36 insertions(+)
>>
>> diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
>> index 07c67ad1a6a07..46b96d062d2db 100644
>> --- a/kernel/bpf/syscall.c
>> +++ b/kernel/bpf/syscall.c
>> @@ -1360,6 +1360,34 @@ static struct btf *get_map_btf(int btf_fd)
>>         return btf;
>>  }
>>
>> +static int map_has_dynptr_in_key_type(struct btf *btf, u32 btf_key_id, u32 key_size)
>> +{
>> +       const struct btf_type *type;
>> +       struct btf_record *record;
>> +       u32 btf_key_size;
>> +
>> +       if (!btf_key_id)
>> +               return 0;
>> +
>> +       type = btf_type_id_size(btf, &btf_key_id, &btf_key_size);
>> +       if (!type || btf_key_size != key_size)
>> +               return -EINVAL;
>> +
>> +       /* For dynptr key, key BTF type must be struct */
>> +       if (!__btf_type_is_struct(type))
>> +               return 0;
>> +
>> +       if (btf_type_is_dynptr(btf, type))
>> +               return 1;
>> +
>> +       record = btf_parse_fields(btf, type, BPF_DYNPTR, key_size);
>> +       if (IS_ERR(record))
>> +               return PTR_ERR(record);
>> +
>> +       btf_record_free(record);
>> +       return !!record;
>> +}
>> +
>>  #define BPF_MAP_CREATE_LAST_FIELD map_token_fd
>>  /* called via syscall */
>>  static int map_create(union bpf_attr *attr)
>> @@ -1398,6 +1426,14 @@ static int map_create(union bpf_attr *attr)
>>                 btf = get_map_btf(attr->btf_fd);
>>                 if (IS_ERR(btf))
>>                         return PTR_ERR(btf);
>> +
>> +               err = map_has_dynptr_in_key_type(btf, attr->btf_key_type_id, attr->key_size);
>> +               if (err < 0)
>> +                       goto put_btf;
>> +               if (err > 0) {
>> +                       attr->map_flags |= BPF_INT_F_DYNPTR_IN_KEY;
> I don't like this inband signaling in the uapi field.
> The whole refactoring in patch 4 to do patch 6 and
> subsequent bpf_map_has_dynptr_key() in various places
> feels like reinventing the wheel.
>
> We already have map_check_btf() mechanism that works for
> existing special fields inside BTF.
> Please use it.

Yes. However map->key_record is only available after the map is created,
but the creation of hash map needs to check it before the map is
created. Instead of using an internal flag, how about adding extra
argument for both ->map_alloc_check() and ->map_alloc() as proposed in
the commit message of the previous patch ?
>
> map_has_dynptr_in_key_type() can be done in map_check_btf()
> after map is created, no ?

No. both ->map_alloc_check() and ->map_alloc() need to know whether
dynptr is enabled (as explained in the previous commit message). Both of
these functions are called before the map is created.
> Then when it passes map->map_type check set a bool inside
> struct bpf_map, so that bpf_map_has_dynptr_key() can be fast
> in the critical path of hashtab.
> Or better yet use:
> static inline bool bpf_map_has_dynptr_key(const struct bpf_map *map)
> {
>   /* key_record is not NULL when the map key contains bpf_dynptr_user */
>   return !!map->key_record;
> }
> since htab_map_hash() has to read key_record anyway,
> hence better D$ access.
> .





[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux