2023-09-28 11:38:27

by Alan Maguire

[permalink] [raw]
Subject: Re: The kernel fails to load the ko file because the btf information in the ko file is inconsistent.

On 22/09/2023 04:47, Xin Liu wrote:
> Hi all:
>
> We've had a confusing problem recently. The kfunc is used in the ko and
> kfunc is registered when the ko is loaded. Even if the code is not
> modified, the ko compiled at different times cannot register kfunc
> success on the kernel. It seems that the inconsistency of btf id causes
> this problem.
>
> Is there any way we can solve this problem at the moment?
>

When this issue has come up before, it has more been about having a
way to have module BTF that does not get invalidated by changes in
vmlinux BTF for tracing purposes - so for cases where perhaps the user
wants to build their module less frequently than the underlying kernel,
but still wants BTF info for tracing.

I'm not totally sure this will apply in the kfunc case you
describe. However what we've discussed is supporting standalone
BTF - where the BTF generated for a module does not rely on vmlinux
BTF as a base, so cannot be invalidated when the underlying vmlinux
BTF changes. The idea is that when such a module is loaded, the
BTF types are remapped however, so it _looks_ like normal split BTF -
it just so happens to be fully self-referential, and is not
de-duplicated relative to the underlying kernel. This remapping
has to be done at module load time, since the BTF ids for the
module will start at last_vmlinux_btf_id + 1. See [1]
for more details.

Would that scheme work in the kfunc case? One problem I see
is the .BTF_ids section would be out of date with respect
to the remapping of BTF ids described above; specifically,
if I understand the process correctly, resolve_btfids would have
constructed the .BTF_ids section with the old BTF ids (starting at
0). Since module load remaps these ids to not clash with vmlinux BTF
ids, the .BTF_ids section would be out of date. So we'd need to
figure out a way to keep these in sync to properly support
standalone BTF. That probably wouldn't be too hard (it's essentialy
just a matter of dynamically adding the last_vmlinux_btf_id to
the various values), but we'd need to think about the mechanics.
Something as simple as when registering a kfunc, checking if
it is a standalone module and adding the required offset to the
local BTF ids would perhaps be enough, but I'd need to dig a bit
more into the kfunc mechanics to be sure. Does that sound right?

Thanks!

Alan

[1]
https://lore.kernel.org/bpf/CAEf4BzYoG9RSMdEFZKp8JG+cXBxJEygd0tAtOn-hvjoFFDWfTA@mail.gmail.com/