> btf: Relocate and expose module inline BTF
TL;DR: Nits only, no bugs: in module inline BTF relocation, the
old_module_type_cnt parameter looks redundant, and the final
btf_set_base_btf()/btf_check_sorted() calls appear unneeded.
> diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
> --- a/kernel/bpf/btf.c
> +++ b/kernel/bpf/btf.c
[ ... ]
> @@ -6922,15 +6922,137 @@ __u32 btf_relocate_id(const struct btf *btf, __u32
> id)
> +static int btf_rebase_inline(struct btf *inline_btf,
> + const struct btf *module_btf,
> + const u32 *module_id_map,
> + const u32 *module_str_map,
> + u32 old_module_type_cnt)
> +{
> + u32 old_start_id = inline_btf->start_id;
> + u32 old_start_str_off = inline_btf->start_str_off;
[ ... ]
> + while ((id = btf_field_iter_next(&it))) {
> + if (!*id)
> + continue;
> + if (*id < old_module_type_cnt) {
> + if (module_id_map)
> + *id = module_id_map[*id];
> + } else if (*id >= old_start_id) {
> + *id += id_delta;
> + } else {
> + return -EINVAL;
> + }
> + }
This isn't a bug, but is the old_module_type_cnt parameter needed?
The only caller passes old_module_type_cnt = btf_nr_types(btf), sampled
before btf_relocate(). inline_btf was parsed by btf_parse_split() against
that same btf, and btf_set_base_btf() sets its start_id to
btf_nr_types(base_btf).
That makes old_module_type_cnt equal to old_start_id, so the final
"else return -EINVAL" branch above does not look reachable. Could
old_start_id be used for both checks and the parameter dropped?
[ ... ]
> + btf_set_base_btf(inline_btf, module_btf);
> + btf_check_sorted(inline_btf);
> + return 0;
> +}
[ ... ]
> @@ -6954,67 +7076,66 @@ static struct btf *btf_parse_module(const char
> *module_name, const void *data,
[ ... ]
> + if (inline_btf) {
> + err = btf_rebase_inline(inline_btf, btf, btf->base_id_map,
> + module_str_map, old_module_type_cnt);
> + if (err) {
> + pr_warn("failed to relocate module [%s] inline BTF:
> %d\n",
> + module_name, err);
> + btf_free(inline_btf);
> + } else {
> + *relocated_inline_data = inline_btf->data;
> + inline_btf->data = NULL;
> + btf_free(inline_btf);
> + }
> + }
This isn't a bug, but are the btf_set_base_btf() and btf_check_sorted()
calls at the end of btf_rebase_inline() needed?
On success, btf_parse_module() only takes inline_btf->data and then calls
btf_free(inline_btf) right away, so the updated start_id, start_str_off and
named_start_id are never read. btf_check_sorted() also runs strcmp() across
the inline types and the result is discarded.
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/37149955093