diff mbox series

[bpf-next,v5,7/9] libbpf: Find correct module BTFs for struct_ops maps and progs.

Message ID 20231017162306.176586-8-thinker.li@gmail.com (mailing list archive)
State Superseded
Delegated to: BPF
Headers show
Series Registrating struct_ops types from modules | expand

Checks

Context Check Description
bpf/vmtest-bpf-next-VM_Test-8 success Logs for veristat
bpf/vmtest-bpf-next-VM_Test-3 fail Logs for build for s390x with gcc
bpf/vmtest-bpf-next-VM_Test-0 success Logs for ${{ matrix.test }} on ${{ matrix.arch }} with ${{ matrix.toolchain_full }}
bpf/vmtest-bpf-next-VM_Test-5 fail Logs for build for x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-2 fail Logs for build for aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-1 success Logs for ShellCheck
bpf/vmtest-bpf-next-VM_Test-6 success Logs for set-matrix
bpf/vmtest-bpf-next-VM_Test-4 fail Logs for build for x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-7 success Logs for veristat
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for bpf-next, async
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 9 this patch: 9
netdev/cc_maintainers warning 7 maintainers not CCed: yonghong.song@linux.dev jolsa@kernel.org kpsingh@kernel.org john.fastabend@gmail.com sdf@google.com daniel@iogearbox.net haoluo@google.com
netdev/build_clang success Errors and warnings before: 9 this patch: 9
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 9 this patch: 9
netdev/checkpatch warning CHECK: Please use a blank line after function/struct/union/enum declarations WARNING: line length of 85 exceeds 80 columns WARNING: line length of 99 exceeds 80 columns
netdev/kdoc success Errors and warnings before: 22 this patch: 22
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-next-PR fail PR summary

Commit Message

Kui-Feng Lee Oct. 17, 2023, 4:23 p.m. UTC
From: Kui-Feng Lee <thinker.li@gmail.com>

Locate the module BTFs for struct_ops maps and progs and pass them to the
kernel. This ensures that the kernel correctly resolves type IDs from the
appropriate module BTFs.

For the map of a struct_ops object, mod_btf is added to bpf_map to keep a
reference to the module BTF. The FD of the module BTF is passed to the
kernel as mod_btf_fd when the struct_ops object is loaded.

For a bpf_struct_ops prog, attach_btf_obj_fd of bpf_prog is the FD of a
module BTF in the kernel.

Signed-off-by: Kui-Feng Lee <thinker.li@gmail.com>
---
 tools/lib/bpf/bpf.c    |  4 ++-
 tools/lib/bpf/bpf.h    |  5 +++-
 tools/lib/bpf/libbpf.c | 68 +++++++++++++++++++++++++++---------------
 3 files changed, 51 insertions(+), 26 deletions(-)

Comments

Andrii Nakryiko Oct. 17, 2023, 9:49 p.m. UTC | #1
On Tue, Oct 17, 2023 at 9:23 AM <thinker.li@gmail.com> wrote:
>
> From: Kui-Feng Lee <thinker.li@gmail.com>
>
> Locate the module BTFs for struct_ops maps and progs and pass them to the
> kernel. This ensures that the kernel correctly resolves type IDs from the
> appropriate module BTFs.
>
> For the map of a struct_ops object, mod_btf is added to bpf_map to keep a
> reference to the module BTF. The FD of the module BTF is passed to the
> kernel as mod_btf_fd when the struct_ops object is loaded.
>
> For a bpf_struct_ops prog, attach_btf_obj_fd of bpf_prog is the FD of a
> module BTF in the kernel.
>
> Signed-off-by: Kui-Feng Lee <thinker.li@gmail.com>
> ---
>  tools/lib/bpf/bpf.c    |  4 ++-
>  tools/lib/bpf/bpf.h    |  5 +++-
>  tools/lib/bpf/libbpf.c | 68 +++++++++++++++++++++++++++---------------
>  3 files changed, 51 insertions(+), 26 deletions(-)
>

I have a few nits, please accommodate them, and with that please add
my ack on libbpf side of things

Acked-by: Andrii Nakryiko <andrii@kernel.org>

> diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
> index b0f1913763a3..af46488e4ea9 100644
> --- a/tools/lib/bpf/bpf.c
> +++ b/tools/lib/bpf/bpf.c
> @@ -169,7 +169,8 @@ int bpf_map_create(enum bpf_map_type map_type,
>                    __u32 max_entries,
>                    const struct bpf_map_create_opts *opts)
>  {
> -       const size_t attr_sz = offsetofend(union bpf_attr, map_extra);
> +       const size_t attr_sz = offsetofend(union bpf_attr,
> +                                          value_type_btf_obj_fd);
>         union bpf_attr attr;
>         int fd;
>
> @@ -191,6 +192,7 @@ int bpf_map_create(enum bpf_map_type map_type,
>         attr.btf_key_type_id = OPTS_GET(opts, btf_key_type_id, 0);
>         attr.btf_value_type_id = OPTS_GET(opts, btf_value_type_id, 0);
>         attr.btf_vmlinux_value_type_id = OPTS_GET(opts, btf_vmlinux_value_type_id, 0);
> +       attr.value_type_btf_obj_fd = OPTS_GET(opts, value_type_btf_obj_fd, 0);
>
>         attr.inner_map_fd = OPTS_GET(opts, inner_map_fd, 0);
>         attr.map_flags = OPTS_GET(opts, map_flags, 0);
> diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
> index 74c2887cfd24..1733cdc21241 100644
> --- a/tools/lib/bpf/bpf.h
> +++ b/tools/lib/bpf/bpf.h
> @@ -51,8 +51,11 @@ struct bpf_map_create_opts {
>
>         __u32 numa_node;
>         __u32 map_ifindex;
> +
> +       __u32 value_type_btf_obj_fd;
> +       size_t:0;
>  };
> -#define bpf_map_create_opts__last_field map_ifindex
> +#define bpf_map_create_opts__last_field value_type_btf_obj_fd
>
>  LIBBPF_API int bpf_map_create(enum bpf_map_type map_type,
>                               const char *map_name,
> diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
> index 3a6108e3238b..d8a60fb52f5c 100644
> --- a/tools/lib/bpf/libbpf.c
> +++ b/tools/lib/bpf/libbpf.c
> @@ -519,6 +519,7 @@ struct bpf_map {
>         struct bpf_map_def def;
>         __u32 numa_node;
>         __u32 btf_var_idx;
> +       int mod_btf_fd;
>         __u32 btf_key_type_id;
>         __u32 btf_value_type_id;
>         __u32 btf_vmlinux_value_type_id;
> @@ -893,6 +894,8 @@ bpf_object__add_programs(struct bpf_object *obj, Elf_Data *sec_data,
>         return 0;
>  }
>
> +static int load_module_btfs(struct bpf_object *obj);
> +

you don't need this forward declaration, do you?

>  static const struct btf_member *
>  find_member_by_offset(const struct btf_type *t, __u32 bit_offset)
>  {
> @@ -922,22 +925,29 @@ find_member_by_name(const struct btf *btf, const struct btf_type *t,
>         return NULL;
>  }
>

[...]

>         if (obj->btf && btf__fd(obj->btf) >= 0) {
>                 create_attr.btf_fd = btf__fd(obj->btf);
> @@ -7700,9 +7718,9 @@ static int bpf_object__read_kallsyms_file(struct bpf_object *obj)
>         return libbpf_kallsyms_parse(kallsyms_cb, obj);
>  }
>
> -static int find_ksym_btf_id(struct bpf_object *obj, const char *ksym_name,
> -                           __u16 kind, struct btf **res_btf,
> -                           struct module_btf **res_mod_btf)
> +static int find_module_btf_id(struct bpf_object *obj, const char *kern_name,
> +                             __u16 kind, struct btf **res_btf,
> +                             struct module_btf **res_mod_btf)

I actually find "find_module" terminology confusing, because it might
not be in the module after all, right? I think "find_ksym_btf_id" is a
totally appropriate name, and it's just that in some cases that kernel
symbol (ksym) will be found in the kernel module instead of in vmlinux
image itself. Still, it's a kernel. Let's keep the name?

>  {
>         struct module_btf *mod_btf;
>         struct btf *btf;

[...]
Kui-Feng Lee Oct. 18, 2023, 2:25 a.m. UTC | #2
On 10/17/23 14:49, Andrii Nakryiko wrote:
> On Tue, Oct 17, 2023 at 9:23 AM <thinker.li@gmail.com> wrote:
>>
>> From: Kui-Feng Lee <thinker.li@gmail.com>
>>
>> Locate the module BTFs for struct_ops maps and progs and pass them to the
>> kernel. This ensures that the kernel correctly resolves type IDs from the
>> appropriate module BTFs.
>>
>> For the map of a struct_ops object, mod_btf is added to bpf_map to keep a
>> reference to the module BTF. The FD of the module BTF is passed to the
>> kernel as mod_btf_fd when the struct_ops object is loaded.
>>
>> For a bpf_struct_ops prog, attach_btf_obj_fd of bpf_prog is the FD of a
>> module BTF in the kernel.
>>
>> Signed-off-by: Kui-Feng Lee <thinker.li@gmail.com>
>> ---
>>   tools/lib/bpf/bpf.c    |  4 ++-
>>   tools/lib/bpf/bpf.h    |  5 +++-
>>   tools/lib/bpf/libbpf.c | 68 +++++++++++++++++++++++++++---------------
>>   3 files changed, 51 insertions(+), 26 deletions(-)
>>
> 
> I have a few nits, please accommodate them, and with that please add
> my ack on libbpf side of things
> 
> Acked-by: Andrii Nakryiko <andrii@kernel.org>


Thanks for reviewing!

> 
>> diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
>> index b0f1913763a3..af46488e4ea9 100644
>> --- a/tools/lib/bpf/bpf.c
>> +++ b/tools/lib/bpf/bpf.c
>> @@ -169,7 +169,8 @@ int bpf_map_create(enum bpf_map_type map_type,
>>                     __u32 max_entries,
>>                     const struct bpf_map_create_opts *opts)
>>   {
>> -       const size_t attr_sz = offsetofend(union bpf_attr, map_extra);
>> +       const size_t attr_sz = offsetofend(union bpf_attr,
>> +                                          value_type_btf_obj_fd);
>>          union bpf_attr attr;
>>          int fd;
>>
>> @@ -191,6 +192,7 @@ int bpf_map_create(enum bpf_map_type map_type,
>>          attr.btf_key_type_id = OPTS_GET(opts, btf_key_type_id, 0);
>>          attr.btf_value_type_id = OPTS_GET(opts, btf_value_type_id, 0);
>>          attr.btf_vmlinux_value_type_id = OPTS_GET(opts, btf_vmlinux_value_type_id, 0);
>> +       attr.value_type_btf_obj_fd = OPTS_GET(opts, value_type_btf_obj_fd, 0);
>>
>>          attr.inner_map_fd = OPTS_GET(opts, inner_map_fd, 0);
>>          attr.map_flags = OPTS_GET(opts, map_flags, 0);
>> diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
>> index 74c2887cfd24..1733cdc21241 100644
>> --- a/tools/lib/bpf/bpf.h
>> +++ b/tools/lib/bpf/bpf.h
>> @@ -51,8 +51,11 @@ struct bpf_map_create_opts {
>>
>>          __u32 numa_node;
>>          __u32 map_ifindex;
>> +
>> +       __u32 value_type_btf_obj_fd;
>> +       size_t:0;
>>   };
>> -#define bpf_map_create_opts__last_field map_ifindex
>> +#define bpf_map_create_opts__last_field value_type_btf_obj_fd
>>
>>   LIBBPF_API int bpf_map_create(enum bpf_map_type map_type,
>>                                const char *map_name,
>> diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
>> index 3a6108e3238b..d8a60fb52f5c 100644
>> --- a/tools/lib/bpf/libbpf.c
>> +++ b/tools/lib/bpf/libbpf.c
>> @@ -519,6 +519,7 @@ struct bpf_map {
>>          struct bpf_map_def def;
>>          __u32 numa_node;
>>          __u32 btf_var_idx;
>> +       int mod_btf_fd;
>>          __u32 btf_key_type_id;
>>          __u32 btf_value_type_id;
>>          __u32 btf_vmlinux_value_type_id;
>> @@ -893,6 +894,8 @@ bpf_object__add_programs(struct bpf_object *obj, Elf_Data *sec_data,
>>          return 0;
>>   }
>>
>> +static int load_module_btfs(struct bpf_object *obj);
>> +
> 
> you don't need this forward declaration, do you?


I will remove it.

> 
>>   static const struct btf_member *
>>   find_member_by_offset(const struct btf_type *t, __u32 bit_offset)
>>   {
>> @@ -922,22 +925,29 @@ find_member_by_name(const struct btf *btf, const struct btf_type *t,
>>          return NULL;
>>   }
>>
> 
> [...]
> 
>>          if (obj->btf && btf__fd(obj->btf) >= 0) {
>>                  create_attr.btf_fd = btf__fd(obj->btf);
>> @@ -7700,9 +7718,9 @@ static int bpf_object__read_kallsyms_file(struct bpf_object *obj)
>>          return libbpf_kallsyms_parse(kallsyms_cb, obj);
>>   }
>>
>> -static int find_ksym_btf_id(struct bpf_object *obj, const char *ksym_name,
>> -                           __u16 kind, struct btf **res_btf,
>> -                           struct module_btf **res_mod_btf)
>> +static int find_module_btf_id(struct bpf_object *obj, const char *kern_name,
>> +                             __u16 kind, struct btf **res_btf,
>> +                             struct module_btf **res_mod_btf)
> 
> I actually find "find_module" terminology confusing, because it might
> not be in the module after all, right? I think "find_ksym_btf_id" is a
> totally appropriate name, and it's just that in some cases that kernel
> symbol (ksym) will be found in the kernel module instead of in vmlinux
> image itself. Still, it's a kernel. Let's keep the name?

Agree!

> 
>>   {
>>          struct module_btf *mod_btf;
>>          struct btf *btf;
> 
> [...]
Martin KaFai Lau Oct. 19, 2023, 2:43 a.m. UTC | #3
On 10/17/23 9:23 AM, thinker.li@gmail.com wrote:
> -static int find_ksym_btf_id(struct bpf_object *obj, const char *ksym_name,
> -			    __u16 kind, struct btf **res_btf,
> -			    struct module_btf **res_mod_btf)
> +static int find_module_btf_id(struct bpf_object *obj, const char *kern_name,
> +			      __u16 kind, struct btf **res_btf,
> +			      struct module_btf **res_mod_btf)
>   {
>   	struct module_btf *mod_btf;
>   	struct btf *btf;
> @@ -7710,7 +7728,7 @@ static int find_ksym_btf_id(struct bpf_object *obj, const char *ksym_name,
>   
>   	btf = obj->btf_vmlinux;
>   	mod_btf = NULL;
> -	id = btf__find_by_name_kind(btf, ksym_name, kind);
> +	id = btf__find_by_name_kind(btf, kern_name, kind);
>   
>   	if (id == -ENOENT) {
>   		err = load_module_btfs(obj);
> @@ -7721,7 +7739,7 @@ static int find_ksym_btf_id(struct bpf_object *obj, const char *ksym_name,
>   			/* we assume module_btf's BTF FD is always >0 */
>   			mod_btf = &obj->btf_modules[i];
>   			btf = mod_btf->btf;
> -			id = btf__find_by_name_kind_own(btf, ksym_name, kind);
> +			id = btf__find_by_name_kind_own(btf, kern_name, kind);
>   			if (id != -ENOENT)
>   				break;
>   		}
> @@ -7744,7 +7762,7 @@ static int bpf_object__resolve_ksym_var_btf_id(struct bpf_object *obj,
>   	struct btf *btf = NULL;
>   	int id, err;
>   
> -	id = find_ksym_btf_id(obj, ext->name, BTF_KIND_VAR, &btf, &mod_btf);
> +	id = find_module_btf_id(obj, ext->name, BTF_KIND_VAR, &btf, &mod_btf);
>   	if (id < 0) {
>   		if (id == -ESRCH && ext->is_weak)
>   			return 0;
> @@ -7798,8 +7816,8 @@ static int bpf_object__resolve_ksym_func_btf_id(struct bpf_object *obj,
>   
>   	local_func_proto_id = ext->ksym.type_id;
>   
> -	kfunc_id = find_ksym_btf_id(obj, ext->essent_name ?: ext->name, BTF_KIND_FUNC, &kern_btf,
> -				    &mod_btf);
> +	kfunc_id = find_module_btf_id(obj, ext->essent_name ?: ext->name, BTF_KIND_FUNC, &kern_btf,
> +				      &mod_btf);
>   	if (kfunc_id < 0) {
>   		if (kfunc_id == -ESRCH && ext->is_weak)
>   			return 0;
> @@ -9464,9 +9482,9 @@ static int libbpf_find_prog_btf_id(const char *name, __u32 attach_prog_fd)
>   	return err;
>   }
>   
> -static int find_kernel_btf_id(struct bpf_object *obj, const char *attach_name,
> -			      enum bpf_attach_type attach_type,
> -			      int *btf_obj_fd, int *btf_type_id)
> +static int find_kernel_attach_btf_id(struct bpf_object *obj, const char *attach_name,
> +				     enum bpf_attach_type attach_type,
> +				     int *btf_obj_fd, int *btf_type_id)
>   {
>   	int ret, i;
>   
> @@ -9531,7 +9549,9 @@ static int libbpf_find_attach_btf_id(struct bpf_program *prog, const char *attac
>   		*btf_obj_fd = 0;
>   		*btf_type_id = 1;
>   	} else {
> -		err = find_kernel_btf_id(prog->obj, attach_name, attach_type, btf_obj_fd, btf_type_id);
> +		err = find_kernel_attach_btf_id(prog->obj, attach_name,
> +						attach_type, btf_obj_fd,
> +						btf_type_id);
>   	}
>   	if (err) {
>   		pr_warn("prog '%s': failed to find kernel BTF type ID of '%s': %d\n",
> @@ -12945,9 +12965,9 @@ int bpf_program__set_attach_target(struct bpf_program *prog,
>   		err = bpf_object__load_vmlinux_btf(prog->obj, true);
>   		if (err)
>   			return libbpf_err(err);
> -		err = find_kernel_btf_id(prog->obj, attach_func_name,
> -					 prog->expected_attach_type,
> -					 &btf_obj_fd, &btf_id);
> +		err = find_kernel_attach_btf_id(prog->obj, attach_func_name,
> +						prog->expected_attach_type,
> +						&btf_obj_fd, &btf_id);

Please avoid mixing this level of name changes with the main changes. It is 
quite confusing for the reviewer and it is not mentioned in the commit message 
either.
Kui-Feng Lee Oct. 19, 2023, 4:31 p.m. UTC | #4
On 10/18/23 19:43, Martin KaFai Lau wrote:
> On 10/17/23 9:23 AM, thinker.li@gmail.com wrote:
>> -static int find_ksym_btf_id(struct bpf_object *obj, const char 
>> *ksym_name,
>> -                __u16 kind, struct btf **res_btf,
>> -                struct module_btf **res_mod_btf)
>> +static int find_module_btf_id(struct bpf_object *obj, const char 
>> *kern_name,
>> +                  __u16 kind, struct btf **res_btf,
>> +                  struct module_btf **res_mod_btf)
>>   {
>>       struct module_btf *mod_btf;
>>       struct btf *btf;
>> @@ -7710,7 +7728,7 @@ static int find_ksym_btf_id(struct bpf_object 
>> *obj, const char *ksym_name,
>>       btf = obj->btf_vmlinux;
>>       mod_btf = NULL;
>> -    id = btf__find_by_name_kind(btf, ksym_name, kind);
>> +    id = btf__find_by_name_kind(btf, kern_name, kind);
>>       if (id == -ENOENT) {
>>           err = load_module_btfs(obj);
>> @@ -7721,7 +7739,7 @@ static int find_ksym_btf_id(struct bpf_object 
>> *obj, const char *ksym_name,
>>               /* we assume module_btf's BTF FD is always >0 */
>>               mod_btf = &obj->btf_modules[i];
>>               btf = mod_btf->btf;
>> -            id = btf__find_by_name_kind_own(btf, ksym_name, kind);
>> +            id = btf__find_by_name_kind_own(btf, kern_name, kind);
>>               if (id != -ENOENT)
>>                   break;
>>           }
>> @@ -7744,7 +7762,7 @@ static int 
>> bpf_object__resolve_ksym_var_btf_id(struct bpf_object *obj,
>>       struct btf *btf = NULL;
>>       int id, err;
>> -    id = find_ksym_btf_id(obj, ext->name, BTF_KIND_VAR, &btf, &mod_btf);
>> +    id = find_module_btf_id(obj, ext->name, BTF_KIND_VAR, &btf, 
>> &mod_btf);
>>       if (id < 0) {
>>           if (id == -ESRCH && ext->is_weak)
>>               return 0;
>> @@ -7798,8 +7816,8 @@ static int 
>> bpf_object__resolve_ksym_func_btf_id(struct bpf_object *obj,
>>       local_func_proto_id = ext->ksym.type_id;
>> -    kfunc_id = find_ksym_btf_id(obj, ext->essent_name ?: ext->name, 
>> BTF_KIND_FUNC, &kern_btf,
>> -                    &mod_btf);
>> +    kfunc_id = find_module_btf_id(obj, ext->essent_name ?: ext->name, 
>> BTF_KIND_FUNC, &kern_btf,
>> +                      &mod_btf);
>>       if (kfunc_id < 0) {
>>           if (kfunc_id == -ESRCH && ext->is_weak)
>>               return 0;
>> @@ -9464,9 +9482,9 @@ static int libbpf_find_prog_btf_id(const char 
>> *name, __u32 attach_prog_fd)
>>       return err;
>>   }
>> -static int find_kernel_btf_id(struct bpf_object *obj, const char 
>> *attach_name,
>> -                  enum bpf_attach_type attach_type,
>> -                  int *btf_obj_fd, int *btf_type_id)
>> +static int find_kernel_attach_btf_id(struct bpf_object *obj, const 
>> char *attach_name,
>> +                     enum bpf_attach_type attach_type,
>> +                     int *btf_obj_fd, int *btf_type_id)
>>   {
>>       int ret, i;
>> @@ -9531,7 +9549,9 @@ static int libbpf_find_attach_btf_id(struct 
>> bpf_program *prog, const char *attac
>>           *btf_obj_fd = 0;
>>           *btf_type_id = 1;
>>       } else {
>> -        err = find_kernel_btf_id(prog->obj, attach_name, attach_type, 
>> btf_obj_fd, btf_type_id);
>> +        err = find_kernel_attach_btf_id(prog->obj, attach_name,
>> +                        attach_type, btf_obj_fd,
>> +                        btf_type_id);
>>       }
>>       if (err) {
>>           pr_warn("prog '%s': failed to find kernel BTF type ID of 
>> '%s': %d\n",
>> @@ -12945,9 +12965,9 @@ int bpf_program__set_attach_target(struct 
>> bpf_program *prog,
>>           err = bpf_object__load_vmlinux_btf(prog->obj, true);
>>           if (err)
>>               return libbpf_err(err);
>> -        err = find_kernel_btf_id(prog->obj, attach_func_name,
>> -                     prog->expected_attach_type,
>> -                     &btf_obj_fd, &btf_id);
>> +        err = find_kernel_attach_btf_id(prog->obj, attach_func_name,
>> +                        prog->expected_attach_type,
>> +                        &btf_obj_fd, &btf_id);
> 
> Please avoid mixing this level of name changes with the main changes. It 
> is quite confusing for the reviewer and it is not mentioned in the 
> commit message either.

Got it! Sorry confusing.
diff mbox series

Patch

diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index b0f1913763a3..af46488e4ea9 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -169,7 +169,8 @@  int bpf_map_create(enum bpf_map_type map_type,
 		   __u32 max_entries,
 		   const struct bpf_map_create_opts *opts)
 {
-	const size_t attr_sz = offsetofend(union bpf_attr, map_extra);
+	const size_t attr_sz = offsetofend(union bpf_attr,
+					   value_type_btf_obj_fd);
 	union bpf_attr attr;
 	int fd;
 
@@ -191,6 +192,7 @@  int bpf_map_create(enum bpf_map_type map_type,
 	attr.btf_key_type_id = OPTS_GET(opts, btf_key_type_id, 0);
 	attr.btf_value_type_id = OPTS_GET(opts, btf_value_type_id, 0);
 	attr.btf_vmlinux_value_type_id = OPTS_GET(opts, btf_vmlinux_value_type_id, 0);
+	attr.value_type_btf_obj_fd = OPTS_GET(opts, value_type_btf_obj_fd, 0);
 
 	attr.inner_map_fd = OPTS_GET(opts, inner_map_fd, 0);
 	attr.map_flags = OPTS_GET(opts, map_flags, 0);
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
index 74c2887cfd24..1733cdc21241 100644
--- a/tools/lib/bpf/bpf.h
+++ b/tools/lib/bpf/bpf.h
@@ -51,8 +51,11 @@  struct bpf_map_create_opts {
 
 	__u32 numa_node;
 	__u32 map_ifindex;
+
+	__u32 value_type_btf_obj_fd;
+	size_t:0;
 };
-#define bpf_map_create_opts__last_field map_ifindex
+#define bpf_map_create_opts__last_field value_type_btf_obj_fd
 
 LIBBPF_API int bpf_map_create(enum bpf_map_type map_type,
 			      const char *map_name,
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 3a6108e3238b..d8a60fb52f5c 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -519,6 +519,7 @@  struct bpf_map {
 	struct bpf_map_def def;
 	__u32 numa_node;
 	__u32 btf_var_idx;
+	int mod_btf_fd;
 	__u32 btf_key_type_id;
 	__u32 btf_value_type_id;
 	__u32 btf_vmlinux_value_type_id;
@@ -893,6 +894,8 @@  bpf_object__add_programs(struct bpf_object *obj, Elf_Data *sec_data,
 	return 0;
 }
 
+static int load_module_btfs(struct bpf_object *obj);
+
 static const struct btf_member *
 find_member_by_offset(const struct btf_type *t, __u32 bit_offset)
 {
@@ -922,22 +925,29 @@  find_member_by_name(const struct btf *btf, const struct btf_type *t,
 	return NULL;
 }
 
+static int find_module_btf_id(struct bpf_object *obj, const char *kern_name,
+			      __u16 kind, struct btf **res_btf,
+			      struct module_btf **res_mod_btf);
+
 #define STRUCT_OPS_VALUE_PREFIX "bpf_struct_ops_"
 static int find_btf_by_prefix_kind(const struct btf *btf, const char *prefix,
 				   const char *name, __u32 kind);
 
 static int
-find_struct_ops_kern_types(const struct btf *btf, const char *tname,
+find_struct_ops_kern_types(struct bpf_object *obj, const char *tname,
+			   struct module_btf **mod_btf,
 			   const struct btf_type **type, __u32 *type_id,
 			   const struct btf_type **vtype, __u32 *vtype_id,
 			   const struct btf_member **data_member)
 {
 	const struct btf_type *kern_type, *kern_vtype;
 	const struct btf_member *kern_data_member;
+	struct btf *btf;
 	__s32 kern_vtype_id, kern_type_id;
 	__u32 i;
 
-	kern_type_id = btf__find_by_name_kind(btf, tname, BTF_KIND_STRUCT);
+	kern_type_id = find_module_btf_id(obj, tname, BTF_KIND_STRUCT,
+					  &btf, mod_btf);
 	if (kern_type_id < 0) {
 		pr_warn("struct_ops init_kern: struct %s is not found in kernel BTF\n",
 			tname);
@@ -991,14 +1001,16 @@  static bool bpf_map__is_struct_ops(const struct bpf_map *map)
 }
 
 /* Init the map's fields that depend on kern_btf */
-static int bpf_map__init_kern_struct_ops(struct bpf_map *map,
-					 const struct btf *btf,
-					 const struct btf *kern_btf)
+static int bpf_map__init_kern_struct_ops(struct bpf_map *map)
 {
 	const struct btf_member *member, *kern_member, *kern_data_member;
 	const struct btf_type *type, *kern_type, *kern_vtype;
 	__u32 i, kern_type_id, kern_vtype_id, kern_data_off;
+	struct bpf_object *obj = map->obj;
+	const struct btf *btf = obj->btf;
 	struct bpf_struct_ops *st_ops;
+	const struct btf *kern_btf;
+	struct module_btf *mod_btf;
 	void *data, *kern_data;
 	const char *tname;
 	int err;
@@ -1006,16 +1018,19 @@  static int bpf_map__init_kern_struct_ops(struct bpf_map *map,
 	st_ops = map->st_ops;
 	type = st_ops->type;
 	tname = st_ops->tname;
-	err = find_struct_ops_kern_types(kern_btf, tname,
+	err = find_struct_ops_kern_types(obj, tname, &mod_btf,
 					 &kern_type, &kern_type_id,
 					 &kern_vtype, &kern_vtype_id,
 					 &kern_data_member);
 	if (err)
 		return err;
 
+	kern_btf = mod_btf ? mod_btf->btf : obj->btf_vmlinux;
+
 	pr_debug("struct_ops init_kern %s: type_id:%u kern_type_id:%u kern_vtype_id:%u\n",
 		 map->name, st_ops->type_id, kern_type_id, kern_vtype_id);
 
+	map->mod_btf_fd = mod_btf ? mod_btf->fd : 0;
 	map->def.value_size = kern_vtype->size;
 	map->btf_vmlinux_value_type_id = kern_vtype_id;
 
@@ -1091,6 +1106,8 @@  static int bpf_map__init_kern_struct_ops(struct bpf_map *map,
 				return -ENOTSUP;
 			}
 
+			if (mod_btf)
+				prog->attach_btf_obj_fd = mod_btf->fd;
 			prog->attach_btf_id = kern_type_id;
 			prog->expected_attach_type = kern_member_idx;
 
@@ -1133,8 +1150,7 @@  static int bpf_object__init_kern_struct_ops_maps(struct bpf_object *obj)
 		if (!bpf_map__is_struct_ops(map))
 			continue;
 
-		err = bpf_map__init_kern_struct_ops(map, obj->btf,
-						    obj->btf_vmlinux);
+		err = bpf_map__init_kern_struct_ops(map);
 		if (err)
 			return err;
 	}
@@ -5193,8 +5209,10 @@  static int bpf_object__create_map(struct bpf_object *obj, struct bpf_map *map, b
 	create_attr.numa_node = map->numa_node;
 	create_attr.map_extra = map->map_extra;
 
-	if (bpf_map__is_struct_ops(map))
+	if (bpf_map__is_struct_ops(map)) {
 		create_attr.btf_vmlinux_value_type_id = map->btf_vmlinux_value_type_id;
+		create_attr.value_type_btf_obj_fd = map->mod_btf_fd;
+	}
 
 	if (obj->btf && btf__fd(obj->btf) >= 0) {
 		create_attr.btf_fd = btf__fd(obj->btf);
@@ -7700,9 +7718,9 @@  static int bpf_object__read_kallsyms_file(struct bpf_object *obj)
 	return libbpf_kallsyms_parse(kallsyms_cb, obj);
 }
 
-static int find_ksym_btf_id(struct bpf_object *obj, const char *ksym_name,
-			    __u16 kind, struct btf **res_btf,
-			    struct module_btf **res_mod_btf)
+static int find_module_btf_id(struct bpf_object *obj, const char *kern_name,
+			      __u16 kind, struct btf **res_btf,
+			      struct module_btf **res_mod_btf)
 {
 	struct module_btf *mod_btf;
 	struct btf *btf;
@@ -7710,7 +7728,7 @@  static int find_ksym_btf_id(struct bpf_object *obj, const char *ksym_name,
 
 	btf = obj->btf_vmlinux;
 	mod_btf = NULL;
-	id = btf__find_by_name_kind(btf, ksym_name, kind);
+	id = btf__find_by_name_kind(btf, kern_name, kind);
 
 	if (id == -ENOENT) {
 		err = load_module_btfs(obj);
@@ -7721,7 +7739,7 @@  static int find_ksym_btf_id(struct bpf_object *obj, const char *ksym_name,
 			/* we assume module_btf's BTF FD is always >0 */
 			mod_btf = &obj->btf_modules[i];
 			btf = mod_btf->btf;
-			id = btf__find_by_name_kind_own(btf, ksym_name, kind);
+			id = btf__find_by_name_kind_own(btf, kern_name, kind);
 			if (id != -ENOENT)
 				break;
 		}
@@ -7744,7 +7762,7 @@  static int bpf_object__resolve_ksym_var_btf_id(struct bpf_object *obj,
 	struct btf *btf = NULL;
 	int id, err;
 
-	id = find_ksym_btf_id(obj, ext->name, BTF_KIND_VAR, &btf, &mod_btf);
+	id = find_module_btf_id(obj, ext->name, BTF_KIND_VAR, &btf, &mod_btf);
 	if (id < 0) {
 		if (id == -ESRCH && ext->is_weak)
 			return 0;
@@ -7798,8 +7816,8 @@  static int bpf_object__resolve_ksym_func_btf_id(struct bpf_object *obj,
 
 	local_func_proto_id = ext->ksym.type_id;
 
-	kfunc_id = find_ksym_btf_id(obj, ext->essent_name ?: ext->name, BTF_KIND_FUNC, &kern_btf,
-				    &mod_btf);
+	kfunc_id = find_module_btf_id(obj, ext->essent_name ?: ext->name, BTF_KIND_FUNC, &kern_btf,
+				      &mod_btf);
 	if (kfunc_id < 0) {
 		if (kfunc_id == -ESRCH && ext->is_weak)
 			return 0;
@@ -9464,9 +9482,9 @@  static int libbpf_find_prog_btf_id(const char *name, __u32 attach_prog_fd)
 	return err;
 }
 
-static int find_kernel_btf_id(struct bpf_object *obj, const char *attach_name,
-			      enum bpf_attach_type attach_type,
-			      int *btf_obj_fd, int *btf_type_id)
+static int find_kernel_attach_btf_id(struct bpf_object *obj, const char *attach_name,
+				     enum bpf_attach_type attach_type,
+				     int *btf_obj_fd, int *btf_type_id)
 {
 	int ret, i;
 
@@ -9531,7 +9549,9 @@  static int libbpf_find_attach_btf_id(struct bpf_program *prog, const char *attac
 		*btf_obj_fd = 0;
 		*btf_type_id = 1;
 	} else {
-		err = find_kernel_btf_id(prog->obj, attach_name, attach_type, btf_obj_fd, btf_type_id);
+		err = find_kernel_attach_btf_id(prog->obj, attach_name,
+						attach_type, btf_obj_fd,
+						btf_type_id);
 	}
 	if (err) {
 		pr_warn("prog '%s': failed to find kernel BTF type ID of '%s': %d\n",
@@ -12945,9 +12965,9 @@  int bpf_program__set_attach_target(struct bpf_program *prog,
 		err = bpf_object__load_vmlinux_btf(prog->obj, true);
 		if (err)
 			return libbpf_err(err);
-		err = find_kernel_btf_id(prog->obj, attach_func_name,
-					 prog->expected_attach_type,
-					 &btf_obj_fd, &btf_id);
+		err = find_kernel_attach_btf_id(prog->obj, attach_func_name,
+						prog->expected_attach_type,
+						&btf_obj_fd, &btf_id);
 		if (err)
 			return libbpf_err(err);
 	}