libbpf: Improve BTF dedup handling of "identical" BTF types
authorAndrii Nakryiko <andrii@kernel.org>
Thu, 1 May 2025 23:52:31 +0000 (16:52 -0700)
committerAlexei Starovoitov <ast@kernel.org>
Mon, 5 May 2025 21:51:47 +0000 (14:51 -0700)
commit62e23f183839c3d718ab36ce1c0cf7cb4b9c05a4
treed94c80a29b45d9adf8f4dab4a3b4c1a3816a804e
parent41948afcf503b5667637a0b3ab279a061f559bec
libbpf: Improve BTF dedup handling of "identical" BTF types

BTF dedup has a strong assumption that compiler with deduplicate identical
types within any given compilation unit (i.e., .c file). This property
is used when establishing equilvalence of two subgraphs of types.

Unfortunately, this property doesn't always holds in practice. We've
seen cases of having truly identical structs, unions, array definitions,
and, most recently, even pointers to the same type being duplicated
within CU.

Previously, we mitigated this on a case-by-case basis, adding a few
simple heuristics for validating that two BTF types (having two
different type IDs) are structurally the same. But this approach scales
poorly, and we can have more weird cases come up in the future.

So let's take a half-step back, and implement a bit more generic
structural equivalence check, recursively. We still limit it to
reasonable depth to avoid long reference loops. Depth-wise limiting of
potentially cyclical graph isn't great, but as I mentioned below doesn't
seem to be detrimental performance-wise. We can always improve this in
the future with per-type visited markers, if necessary.

Performance-wise this doesn't seem too affect vmlinux BTF dedup, which
makes sense because this logic kicks in not so frequently and only if we
already established a canonical candidate type match, but suddenly find
a different (but probably identical) type.

Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Reviewed-by: Alan Maguire <alan.maguire@oracle.com>
Link: https://lore.kernel.org/r/20250501235231.1339822-1-andrii@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/lib/bpf/btf.c