From nobody Tue Dec 2 03:00:26 2025 Received: from mail-pf1-f176.google.com (mail-pf1-f176.google.com [209.85.210.176]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5C5F8334686 for ; Mon, 17 Nov 2025 13:26:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.176 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763386006; cv=none; b=rZ7a3TGMyL6p2zWkdW/2sTraja3kz8ap/ZI09x78zhnXpcxB0fjV8l4+NZLmNcW7bVfr89Z1ATsD9yv5O+62oACQsfck/7A8AFaTxRuLjIKTU2EQOSBVpz1y2XfEKNAOVsU86p4obp+NyA/stxoESTNBIvHP6yS5vN7+4rxXMjE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763386006; c=relaxed/simple; bh=JLTGVx4UZtjRB1mVuoBOiHsEz9/Yagm9RBlqqg5WwaY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=fq6BqH5SsUnDEPq80qiR8kDdSoxhrkU9XJGsMDvL9SVrBoe7Y2gppjZ+ITRv7qPEPcb+Iuq720ZmkGl4PM1l9h7O5Nt59t8T1kV9gnQFlHYdSA6zuFjmj1cEzONM5wuOdUHZR90MgmK/+ZawCqV7edq3c00H/obbLbztvNLz8Z4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=X0wBnSbY; arc=none smtp.client-ip=209.85.210.176 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="X0wBnSbY" Received: by mail-pf1-f176.google.com with SMTP id d2e1a72fcca58-7aae5f2633dso4805071b3a.3 for ; Mon, 17 Nov 2025 05:26:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1763386004; x=1763990804; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=kDnX3/9BOxi6Gb6RG2mMeJXGvVBir6Y+siDzZkdeaTk=; b=X0wBnSbYgbm5aXREpeVRWkwSdB4qG5nl5ftbSg4CslIdKmSJa6jKgQGZevn8tounjT bo6acLsLtuaaJ3Ymyqrc3hux2zPEWsffGyff13iXCbYylf9EDFhbBWxOBgR5JDRH2Hfj 6NmzM2BQVryHgV82sdzl4n7tftAuZB93HOu9UlooQQcvcikXhrTmOqzu1m0UldpcfR/U 9hPLCbP1W++GZfjfOEO2WJO85v/dHKT/ACsMCe9m7rrxjSmWmdNvrRG9lemOUIbA1gki H9h/aKTw087MuFKcf97YlDk1Cbk9lRNKvMTVNc/RjwhzElI4NZOXztYi86O+1oyxHKsk VRHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763386004; x=1763990804; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=kDnX3/9BOxi6Gb6RG2mMeJXGvVBir6Y+siDzZkdeaTk=; b=Yx6eENuNgggLc25JEJV43xWRtnxZtEAa2rlm1CcgCYhdG7fD8CQ/Ao+JNIARz1FwT+ 1PA5rtqT8R7MhAppmVhYcGpy3tCdKVWj5eVRsI4y0dj0p1H547nMmcQoKpePUFkTz4Zq AaEcdPMEiFrfyBDh8y5Ra95V8pXCyhBEq3IzLCvEgpHrsrZnm8wYIOfOUptCUfDXkw3r ShxwASoSJ0viZlrvmNaI8L5OHFu9DIIvc+L2+GAlzyXCXEv0k1xAY9JRoyU2sP0p5+jo tNWgcB4s2rco2QN3ImNAnusozKcSlYomZ6OMaZryAtjZQavl4yk0Rb+X8bM3uZhpuX1d BG4w== X-Forwarded-Encrypted: i=1; AJvYcCW+5KUJ/rbr65CanY3CXIdyuULNKusF0wi8cZhmfGD+jEKjNleMtNy4mmoVn/tAh7CfQD08613UJbNI/bs=@vger.kernel.org X-Gm-Message-State: AOJu0YwWJh1sCGG4mjGd15CZwaZ/9A7948ndjou/c6hHkwulkYy5Aue7 tqveXTkszMOJQddJjKrfrGlalCdRBNOGMRsEoy+S6hHjhrSrn7OTh61D X-Gm-Gg: ASbGncsWBxmPy/TMgdT6cZ2FuCUfRU/P5ZZlhQCIUK9FijQkIkKSgxRwuB6+psaG2kM ykPRvkSQIyaL19+mPQmREWdVuS+lP/30+uVLSt6+/oCREuWvTDyITNdU+MNiH8qEd+4jOKKin6j GW9D4fDdyU5OTW6oYkUUnGnhAKqmGnbFbIW915B3IDAI2HUezMv4Qsw+Gfc9vhmc6l4yrrOycIY IfJhFqqz6E/EaeE5j6iMRc0/p9hF76qduEILqtAzDHgkbShS/3FwI45iqx9oDByJvn0HHbXbBtw e0eomTY4apGwRtkpmKm5/5TyCdk1qUkR5nI1kbW239fJAv0zkBVRWpQiJLxUfI/jFeN5GSS/Ag6 09daFfxW5fZY5vj+5ni8P98Y8YCL2vD0JFnz/Z7Ly1qAVjMVy2gHF7jEkBCruwdxnEbIKGr4r+2 lXJMIH8G31arhNAQBD X-Google-Smtp-Source: AGHT+IGZzgzGPA7A8TF1YDSWzknuJkYXs5j8CBMMrMfBosuB5NpJMGFxMPwzRtMqYCAJYGp+hc7eOg== X-Received: by 2002:a05:6a00:270a:b0:7bf:1a4b:1675 with SMTP id d2e1a72fcca58-7bf1a4b18e8mr4299493b3a.28.1763386003583; Mon, 17 Nov 2025 05:26:43 -0800 (PST) Received: from pengdl-pc.mioffice.cn ([43.224.245.249]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-7b924cd89bcsm13220953b3a.15.2025.11.17.05.26.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Nov 2025 05:26:42 -0800 (PST) From: Donglin Peng 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 , Alan Maguire , Song Liu Subject: [RFC PATCH v6 4/7] libbpf: Optimize type lookup with binary search for sorted BTF Date: Mon, 17 Nov 2025 21:26:20 +0800 Message-Id: <20251117132623.3807094-5-dolinux.peng@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251117132623.3807094-1-dolinux.peng@gmail.com> References: <20251117132623.3807094-1-dolinux.peng@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Donglin Peng This patch introduces binary search optimization for BTF type lookups when the BTF instance contains sorted types. The optimization significantly improves performance when searching for types in large BTF instances with sorted type names. For unsorted BTF or when nr_sorted_types is zero, the implementation falls back to the original linear search algorithm. Cc: Eduard Zingerman Cc: Alexei Starovoitov Cc: Andrii Nakryiko Cc: Alan Maguire Cc: Song Liu Cc: Xiaoqin Zhang Signed-off-by: Donglin Peng --- tools/lib/bpf/btf.c | 104 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 81 insertions(+), 23 deletions(-) diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c index e3aa31c735c8..bb77e6c762cc 100644 --- a/tools/lib/bpf/btf.c +++ b/tools/lib/bpf/btf.c @@ -92,6 +92,12 @@ struct btf { * - for split BTF counts number of types added on top of base BTF. */ __u32 nr_types; + /* number of sorted and named types in this BTF instance: + * - doesn't include special [0] void type; + * - for split BTF counts number of sorted and named types added on + * top of base BTF. + */ + __u32 nr_sorted_types; /* if not NULL, points to the base BTF on top of which the current * split BTF is based */ @@ -897,44 +903,93 @@ int btf__resolve_type(const struct btf *btf, __u32 ty= pe_id) return type_id; } =20 -__s32 btf__find_by_name(const struct btf *btf, const char *type_name) +static __s32 btf_find_type_by_name_bsearch(const struct btf *btf, const ch= ar *name, + __s32 start_id, __s32 end_id) { - __u32 i, nr_types =3D btf__type_cnt(btf); + const struct btf_type *t; + const char *tname; + __s32 l, r, m; + + l =3D start_id; + r =3D end_id; + while (l <=3D r) { + m =3D l + (r - l) / 2; + t =3D btf_type_by_id(btf, m); + tname =3D btf__str_by_offset(btf, t->name_off); + if (strcmp(tname, name) >=3D 0) { + if (l =3D=3D r) + return r; + r =3D m; + } else { + l =3D m + 1; + } + } =20 - if (!strcmp(type_name, "void")) - return 0; + return btf__type_cnt(btf); +} =20 - for (i =3D 1; i < nr_types; i++) { - const struct btf_type *t =3D btf__type_by_id(btf, i); - const char *name =3D btf__name_by_offset(btf, t->name_off); +static __s32 btf_find_type_by_name_kind(const struct btf *btf, int start_i= d, + const char *type_name, __u32 kind) +{ + const struct btf_type *t; + const char *tname; + int err =3D -ENOENT; + + if (start_id < btf->start_id) { + err =3D btf_find_type_by_name_kind(btf->base_btf, start_id, + type_name, kind); + if (err > 0) + goto out; + start_id =3D btf->start_id; + } + + if (btf->nr_sorted_types > 0) { + /* binary search */ + __s32 end_id; + int idx; + + end_id =3D btf->start_id + btf->nr_sorted_types - 1; + idx =3D btf_find_type_by_name_bsearch(btf, type_name, start_id, end_id); + for (; idx <=3D end_id; idx++) { + t =3D btf__type_by_id(btf, idx); + tname =3D btf__str_by_offset(btf, t->name_off); + if (strcmp(tname, type_name)) + goto out; + if (kind =3D=3D -1 || btf_kind(t) =3D=3D kind) + return idx; + } + } else { + /* linear search */ + __u32 i, total; =20 - if (name && !strcmp(type_name, name)) - return i; + total =3D btf__type_cnt(btf); + for (i =3D start_id; i < total; i++) { + t =3D btf_type_by_id(btf, i); + if (kind !=3D -1 && btf_kind(t) !=3D kind) + continue; + tname =3D btf__str_by_offset(btf, t->name_off); + if (tname && !strcmp(tname, type_name)) + return i; + } } =20 - return libbpf_err(-ENOENT); +out: + return err; } =20 static __s32 btf_find_by_name_kind(const struct btf *btf, int start_id, const char *type_name, __u32 kind) { - __u32 i, nr_types =3D btf__type_cnt(btf); - if (kind =3D=3D BTF_KIND_UNKN || !strcmp(type_name, "void")) return 0; =20 - for (i =3D start_id; i < nr_types; i++) { - const struct btf_type *t =3D btf__type_by_id(btf, i); - const char *name; - - if (btf_kind(t) !=3D kind) - continue; - name =3D btf__name_by_offset(btf, t->name_off); - if (name && !strcmp(type_name, name)) - return i; - } + return libbpf_err(btf_find_type_by_name_kind(btf, start_id, type_name, ki= nd)); +} =20 - return libbpf_err(-ENOENT); +/* the kind value of -1 indicates that kind matching should be skipped */ +__s32 btf__find_by_name(const struct btf *btf, const char *type_name) +{ + return btf_find_by_name_kind(btf, btf->start_id, type_name, -1); } =20 __s32 btf__find_by_name_kind_own(const struct btf *btf, const char *type_n= ame, @@ -1006,6 +1061,7 @@ static struct btf *btf_new_empty(struct btf *base_btf) btf->fd =3D -1; btf->ptr_sz =3D sizeof(void *); btf->swapped_endian =3D false; + btf->nr_sorted_types =3D 0; =20 if (base_btf) { btf->base_btf =3D base_btf; @@ -1057,6 +1113,7 @@ static struct btf *btf_new(const void *data, __u32 si= ze, struct btf *base_btf, b btf->start_id =3D 1; btf->start_str_off =3D 0; btf->fd =3D -1; + btf->nr_sorted_types =3D 0; =20 if (base_btf) { btf->base_btf =3D base_btf; @@ -1715,6 +1772,7 @@ static void btf_invalidate_raw_data(struct btf *btf) free(btf->raw_data_swapped); btf->raw_data_swapped =3D NULL; } + btf->nr_sorted_types =3D 0; } =20 /* Ensure BTF is ready to be modified (by splitting into a three memory --=20 2.34.1