From: pengdonglin This patch checks whether the BTF is sorted by name in ascending order. If sorted, binary search will be used when looking up types. Cc: Eduard Zingerman Cc: Alexei Starovoitov Cc: Andrii Nakryiko Cc: Alan Maguire Cc: Ihor Solodrai Cc: Xiaoqin Zhang Signed-off-by: pengdonglin --- tools/lib/bpf/btf.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c index 2facb57d7e5f..c63d46b7d74b 100644 --- a/tools/lib/bpf/btf.c +++ b/tools/lib/bpf/btf.c @@ -899,6 +899,46 @@ int btf__resolve_type(const struct btf *btf, __u32 type_id) return type_id; } +/* + * Assuming that types are sorted by name in ascending order. + */ +static int btf_compare_type_names(__u32 *a, __u32 *b, const struct btf *btf) +{ + struct btf_type *ta = btf_type_by_id(btf, *a); + struct btf_type *tb = btf_type_by_id(btf, *b); + const char *na, *nb; + + na = btf__str_by_offset(btf, ta->name_off); + nb = btf__str_by_offset(btf, tb->name_off); + return strcmp(na, nb); +} + +static void btf_check_sorted(struct btf *btf) +{ + const struct btf_type *t; + __u32 i, k, n; + __u32 sorted_start_id; + + if (btf->nr_types < 2) + return; + + sorted_start_id = 0; + n = btf__type_cnt(btf); + for (i = btf->start_id; i < n; i++) { + k = i + 1; + if (k < n && btf_compare_type_names(&i, &k, btf) > 0) + return; + if (sorted_start_id == 0) { + t = btf_type_by_id(btf, i); + if (t->name_off) + sorted_start_id = i; + } + } + + if (sorted_start_id) + btf->sorted_start_id = sorted_start_id; +} + static __s32 btf_find_by_name_bsearch(const struct btf *btf, const char *name, __s32 start_id, __s32 end_id) { @@ -1147,6 +1187,7 @@ static struct btf *btf_new(const void *data, __u32 size, struct btf *base_btf, b err = err ?: btf_sanity_check(btf); if (err) goto done; + btf_check_sorted(btf); done: if (err) { -- 2.34.1