public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Donglin Peng <dolinux.peng@gmail.com>
To: ast@kernel.org
Cc: eddyz87@gmail.com, andrii.nakryiko@gmail.com,
	zhangxiaoqin@xiaomi.com, linux-kernel@vger.kernel.org,
	bpf@vger.kernel.org, Donglin Peng <dolinux.peng@gmail.com>,
	Alan Maguire <alan.maguire@oracle.com>,
	Song Liu <song@kernel.org>, Donglin Peng <pengdonglin@xiaomi.com>
Subject: [PATCH v5 4/7] libbpf: Implement lazy sorting validation for binary search optimization
Date: Thu,  6 Nov 2025 21:19:53 +0800	[thread overview]
Message-ID: <20251106131956.1222864-5-dolinux.peng@gmail.com> (raw)
In-Reply-To: <20251106131956.1222864-1-dolinux.peng@gmail.com>

From: Donglin Peng <pengdonglin@xiaomi.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@gmail.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Andrii Nakryiko <andrii.nakryiko@gmail.com>
Cc: Alan Maguire <alan.maguire@oracle.com>
Cc: Song Liu <song@kernel.org>
Cc: Xiaoqin Zhang <zhangxiaoqin@xiaomi.com>
Signed-off-by: Donglin Peng <pengdonglin@xiaomi.com>
Signed-off-by: Donglin Peng <dolinux.peng@gmail.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


  parent reply	other threads:[~2025-11-06 13:20 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-11-06 13:19 [PATCH v5 0/7] BTF performance optimizations with permutation and binary search Donglin Peng
2025-11-06 13:19 ` [PATCH v5 1/7] libbpf: Extract BTF type remapping logic into helper function Donglin Peng
2025-11-06 13:19 ` [PATCH v5 2/7] libbpf: Add BTF permutation support for type reordering Donglin Peng
2025-11-06 13:47   ` bot+bpf-ci
2025-11-07  7:12     ` Donglin Peng
2025-11-06 13:19 ` [PATCH v5 3/7] libbpf: Optimize type lookup with binary search for sorted BTF Donglin Peng
2025-11-06 13:40   ` bot+bpf-ci
2025-11-07  7:29     ` Donglin Peng
2025-11-06 13:19 ` Donglin Peng [this message]
2025-11-06 13:19 ` [PATCH v5 5/7] btf: Optimize type lookup with binary search Donglin Peng
2025-11-06 13:19 ` [PATCH v5 6/7] btf: Add lazy sorting validation for " Donglin Peng
2025-11-06 13:47   ` bot+bpf-ci
2025-11-07  7:08     ` Donglin Peng
2025-11-07 18:19       ` Eduard Zingerman
2025-11-07 18:54         ` Alexei Starovoitov
2025-11-07 18:58           ` Eduard Zingerman
2025-11-07 19:01             ` Alexei Starovoitov
2025-11-07 19:51               ` Eduard Zingerman
2025-11-10  1:42                 ` Donglin Peng
2025-11-10 20:44                   ` Eduard Zingerman
2025-11-11  2:07                     ` Donglin Peng
2025-11-06 13:19 ` [PATCH v5 7/7] selftests/bpf: Add test cases for btf__permute functionality Donglin Peng

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20251106131956.1222864-5-dolinux.peng@gmail.com \
    --to=dolinux.peng@gmail.com \
    --cc=alan.maguire@oracle.com \
    --cc=andrii.nakryiko@gmail.com \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=eddyz87@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pengdonglin@xiaomi.com \
    --cc=song@kernel.org \
    --cc=zhangxiaoqin@xiaomi.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox