]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
bpf: Optimize the performance of find_bpffs_btf_enums
authorDonglin Peng <pengdonglin@xiaomi.com>
Fri, 9 Jan 2026 13:00:01 +0000 (21:00 +0800)
committerAndrii Nakryiko <andrii@kernel.org>
Wed, 14 Jan 2026 00:21:36 +0000 (16:21 -0800)
Currently, vmlinux BTF is unconditionally sorted during
the build phase. The function btf_find_by_name_kind
executes the binary search branch, so find_bpffs_btf_enums
can be optimized by using btf_find_by_name_kind.

Signed-off-by: Donglin Peng <pengdonglin@xiaomi.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/bpf/20260109130003.3313716-10-dolinux.peng@gmail.com
kernel/bpf/inode.c

index 9f866a010dada8aeb99e4dfb865590c57cce5ecd..005ea3a2cda74d941a1a67a1db7ba3a8dba7a8f8 100644 (file)
@@ -600,10 +600,17 @@ struct bpffs_btf_enums {
 
 static int find_bpffs_btf_enums(struct bpffs_btf_enums *info)
 {
+       struct {
+               const struct btf_type **type;
+               const char *name;
+       } btf_enums[] = {
+               {&info->cmd_t,          "bpf_cmd"},
+               {&info->map_t,          "bpf_map_type"},
+               {&info->prog_t,         "bpf_prog_type"},
+               {&info->attach_t,       "bpf_attach_type"},
+       };
        const struct btf *btf;
-       const struct btf_type *t;
-       const char *name;
-       int i, n;
+       int i, id;
 
        memset(info, 0, sizeof(*info));
 
@@ -615,31 +622,16 @@ static int find_bpffs_btf_enums(struct bpffs_btf_enums *info)
 
        info->btf = btf;
 
-       for (i = 1, n = btf_nr_types(btf); i < n; i++) {
-               t = btf_type_by_id(btf, i);
-               if (!btf_type_is_enum(t))
-                       continue;
-
-               name = btf_name_by_offset(btf, t->name_off);
-               if (!name)
-                       continue;
-
-               if (strcmp(name, "bpf_cmd") == 0)
-                       info->cmd_t = t;
-               else if (strcmp(name, "bpf_map_type") == 0)
-                       info->map_t = t;
-               else if (strcmp(name, "bpf_prog_type") == 0)
-                       info->prog_t = t;
-               else if (strcmp(name, "bpf_attach_type") == 0)
-                       info->attach_t = t;
-               else
-                       continue;
+       for (i = 0; i < ARRAY_SIZE(btf_enums); i++) {
+               id = btf_find_by_name_kind(btf, btf_enums[i].name,
+                                          BTF_KIND_ENUM);
+               if (id < 0)
+                       return -ESRCH;
 
-               if (info->cmd_t && info->map_t && info->prog_t && info->attach_t)
-                       return 0;
+               *btf_enums[i].type = btf_type_by_id(btf, id);
        }
 
-       return -ESRCH;
+       return 0;
 }
 
 static bool find_btf_enum_const(const struct btf *btf, const struct btf_type *enum_t,