[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20251106131956.1222864-5-dolinux.peng@gmail.com>
Date: Thu, 6 Nov 2025 21:19:53 +0800
From: Donglin Peng <dolinux.peng@...il.com>
To: ast@...nel.org
Cc: eddyz87@...il.com,
andrii.nakryiko@...il.com,
zhangxiaoqin@...omi.com,
linux-kernel@...r.kernel.org,
bpf@...r.kernel.org,
Donglin Peng <dolinux.peng@...il.com>,
Alan Maguire <alan.maguire@...cle.com>,
Song Liu <song@...nel.org>,
Donglin Peng <pengdonglin@...omi.com>
Subject: [PATCH v5 4/7] libbpf: Implement lazy sorting validation for binary search optimization
From: Donglin Peng <pengdonglin@...omi.com>
This patch adds lazy validation of BTF type ordering to determine if types
are sorted by name. The check is performed on first access and cached,
enabling efficient binary search for sorted BTF while maintaining linear
search fallback for unsorted cases.
Cc: Eduard Zingerman <eddyz87@...il.com>
Cc: Alexei Starovoitov <ast@...nel.org>
Cc: Andrii Nakryiko <andrii.nakryiko@...il.com>
Cc: Alan Maguire <alan.maguire@...cle.com>
Cc: Song Liu <song@...nel.org>
Cc: Xiaoqin Zhang <zhangxiaoqin@...omi.com>
Signed-off-by: Donglin Peng <pengdonglin@...omi.com>
Signed-off-by: Donglin Peng <dolinux.peng@...il.com>
---
tools/lib/bpf/btf.c | 69 ++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 68 insertions(+), 1 deletion(-)
diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
index be092892c4ae..56e555c43712 100644
--- a/tools/lib/bpf/btf.c
+++ b/tools/lib/bpf/btf.c
@@ -911,6 +911,73 @@ int btf__resolve_type(const struct btf *btf, __u32 type_id)
return type_id;
}
+/* Anonymous types (with empty names) are considered greater than named types
+ * and are sorted after them. Two anonymous types are considered equal. Named
+ * types are compared lexicographically.
+ */
+static int btf_compare_type_names(const void *a, const void *b, void *priv)
+{
+ struct btf *btf = (struct btf *)priv;
+ struct btf_type *ta = btf_type_by_id(btf, *(__u32 *)a);
+ struct btf_type *tb = btf_type_by_id(btf, *(__u32 *)b);
+ const char *na, *nb;
+ bool anon_a, anon_b;
+
+ na = btf__str_by_offset(btf, ta->name_off);
+ nb = btf__str_by_offset(btf, tb->name_off);
+ anon_a = str_is_empty(na);
+ anon_b = str_is_empty(nb);
+
+ if (anon_a && !anon_b)
+ return 1;
+ if (!anon_a && anon_b)
+ return -1;
+ if (anon_a && anon_b)
+ return 0;
+
+ return strcmp(na, nb);
+}
+
+/* Verifies that BTF types are sorted in ascending order according to their
+ * names, with named types appearing before anonymous types. If the ordering
+ * is correct, counts the number of named types and updates the BTF object's
+ * nr_sorted_types field.
+ *
+ * Return: true if types are properly sorted, false otherwise
+ */
+static bool btf_check_sorted(struct btf *btf)
+{
+ const struct btf_type *t;
+ int i, k = 0, n, nr_sorted_types;
+
+ if (likely(btf->nr_sorted_types != BTF_NEED_SORT_CHECK))
+ goto out;
+ btf->nr_sorted_types = 0;
+
+ if (btf->nr_types < 2)
+ goto out;
+
+ nr_sorted_types = 0;
+ n = btf__type_cnt(btf) - 1;
+ for (i = btf->start_id; i < n; i++) {
+ k = i + 1;
+ if (btf_compare_type_names(&i, &k, btf) > 0)
+ goto out;
+ t = btf_type_by_id(btf, i);
+ if (!str_is_empty(btf__str_by_offset(btf, t->name_off)))
+ nr_sorted_types++;
+ }
+
+ t = btf_type_by_id(btf, k);
+ if (!str_is_empty(btf__str_by_offset(btf, t->name_off)))
+ nr_sorted_types++;
+ if (nr_sorted_types)
+ btf->nr_sorted_types = nr_sorted_types;
+
+out:
+ return btf->nr_sorted_types > 0;
+}
+
/* Performs binary search within specified type ID range to find the leftmost
* BTF type matching the given name. The search assumes types are sorted by
* name in lexicographical order within the specified range.
@@ -970,7 +1037,7 @@ static __s32 btf_find_type_by_name_kind(const struct btf *btf, int start_id,
start_id = btf->start_id;
}
- if (btf->nr_sorted_types != BTF_NEED_SORT_CHECK) {
+ if (btf_check_sorted((struct btf *)btf)) {
/* binary search */
__s32 end_id;
bool skip_first;
--
2.34.1
Powered by blists - more mailing lists