Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion include/linux/btf.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,11 @@ bool btf_is_module(const struct btf *btf);
bool btf_is_vmlinux(const struct btf *btf);
struct module *btf_try_get_module(const struct btf *btf);
u32 btf_nr_types(const struct btf *btf);
struct btf *btf_base_btf(const struct btf *btf);
u32 btf_type_cnt(const struct btf *btf);
u32 btf_start_id(const struct btf *btf);
u32 btf_nr_sorted_types(const struct btf *btf);
void btf_set_nr_sorted_types(struct btf *btf, u32 nr);
struct btf* btf_base_btf(const struct btf *btf);
bool btf_type_is_i32(const struct btf_type *t);
bool btf_type_is_i64(const struct btf_type *t);
bool btf_type_is_primitive(const struct btf_type *t);
Expand Down Expand Up @@ -594,6 +598,10 @@ int get_kern_ctx_btf_id(struct bpf_verifier_log *log, enum bpf_prog_type prog_ty
bool btf_types_are_same(const struct btf *btf1, u32 id1,
const struct btf *btf2, u32 id2);
int btf_check_iter_arg(struct btf *btf, const struct btf_type *func, int arg_idx);
int btf_compare_type_kinds_names(const void *a, const void *b, void *priv);
s32 find_btf_by_name_kind(const struct btf *btf, int start_id, const char *type_name,
u32 kind);
void btf_check_sorted(struct btf *btf, int start_id);

static inline bool btf_type_is_struct_ptr(struct btf *btf, const struct btf_type *t)
{
Expand Down Expand Up @@ -682,5 +690,16 @@ static inline int btf_check_iter_arg(struct btf *btf, const struct btf_type *fun
{
return -EOPNOTSUPP;
}
static inline int btf_compare_type_kinds_names(const void *a, const void *b, void *priv)
{
return -EOPNOTSUPP;
}
static inline s32 find_btf_by_name_kind(const struct btf *btf, int start_id, const char *type_name,
u32 kind)
{
return -EOPNOTSUPP;
}
static inline void btf_check_sorted(struct btf *btf, int start_id);
{}
#endif
#endif
8 changes: 8 additions & 0 deletions kernel/bpf/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,12 @@ config BPF_LSM

If you are unsure how to answer this question, answer N.

config BPF_SORT_BTF_BY_KIND_NAME
bool "Sort BTF types by kind and name"
depends on BPF_SYSCALL
help
This option sorts BTF types in vmlinux and kernel modules by their
kind and name, enabling binary search for btf_find_by_name_kind()
and significantly improving its lookup performance.

endmenu # "BPF subsystem"
1 change: 1 addition & 0 deletions kernel/bpf/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ obj-$(CONFIG_BPF_SYSCALL) += kmem_cache_iter.o
ifeq ($(CONFIG_DMA_SHARED_BUFFER),y)
obj-$(CONFIG_BPF_SYSCALL) += dmabuf_iter.o
endif
obj-$(CONFIG_BPF_SYSCALL) += btf_sort.o

CFLAGS_REMOVE_percpu_freelist.o = $(CC_FLAGS_FTRACE)
CFLAGS_REMOVE_bpf_lru_list.o = $(CC_FLAGS_FTRACE)
Expand Down
36 changes: 22 additions & 14 deletions kernel/bpf/btf.c
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ struct btf {
void *nohdr_data;
struct btf_header hdr;
u32 nr_types; /* includes VOID for base BTF */
u32 nr_sorted_types;
u32 types_size;
u32 data_size;
refcount_t refcnt;
Expand Down Expand Up @@ -544,24 +545,29 @@ u32 btf_nr_types(const struct btf *btf)
return total;
}

s32 btf_find_by_name_kind(const struct btf *btf, const char *name, u8 kind)
u32 btf_start_id(const struct btf *btf)
{
const struct btf_type *t;
const char *tname;
u32 i, total;
return btf->start_id;
}

total = btf_nr_types(btf);
for (i = 1; i < total; i++) {
t = btf_type_by_id(btf, i);
if (BTF_INFO_KIND(t->info) != kind)
continue;
u32 btf_nr_sorted_types(const struct btf *btf)
{
return btf->nr_sorted_types;
}

tname = btf_name_by_offset(btf, t->name_off);
if (!strcmp(tname, name))
return i;
}
void btf_set_nr_sorted_types(struct btf *btf, u32 nr)
{
btf->nr_sorted_types = nr;
}

return -ENOENT;
u32 btf_type_cnt(const struct btf *btf)
{
return btf->start_id + btf->nr_types;
}

s32 btf_find_by_name_kind(const struct btf *btf, const char *name, u8 kind)
{
return find_btf_by_name_kind(btf, 1, name, kind);
}

s32 bpf_find_btf_id(const char *name, u32 kind, struct btf **btf_p)
Expand Down Expand Up @@ -6230,6 +6236,7 @@ static struct btf *btf_parse_base(struct btf_verifier_env *env, const char *name
if (err)
goto errout;

btf_check_sorted(btf, 1);
refcount_set(&btf->refcnt, 1);

return btf;
Expand Down Expand Up @@ -6362,6 +6369,7 @@ static struct btf *btf_parse_module(const char *module_name, const void *data,
base_btf = vmlinux_btf;
}

btf_check_sorted(btf, btf_nr_types(base_btf));
btf_verifier_env_free(env);
refcount_set(&btf->refcnt, 1);
return btf;
Expand Down
2 changes: 2 additions & 0 deletions kernel/bpf/btf_sort.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
#include "../../tools/lib/bpf/btf_sort.c"
5 changes: 5 additions & 0 deletions scripts/Makefile.btf
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ ifneq ($(KBUILD_EXTMOD),)
module-pahole-flags-$(call test-ge, $(pahole-ver), 128) += --btf_features=distilled_base
endif

ifeq ($(call test-ge, $(pahole-ver), 132),y)
pahole-flags-$(CONFIG_BPF_SORT_BTF_BY_KIND_NAME) += --btf_features=sort
module-pahole-flags-$(CONFIG_BPF_SORT_BTF_BY_KIND_NAME) += --btf_features=sort
endif

endif

pahole-flags-$(CONFIG_PAHOLE_HAS_LANG_EXCLUDE) += --lang_exclude=rust
Expand Down
2 changes: 1 addition & 1 deletion tools/lib/bpf/Build
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
libbpf-y := libbpf.o bpf.o nlattr.o btf.o libbpf_utils.o \
netlink.o bpf_prog_linfo.o libbpf_probes.o hashmap.o \
btf_dump.o ringbuf.o strset.o linker.o gen_loader.o relo_core.o \
usdt.o zip.o elf.o features.o btf_iter.o btf_relocate.o
usdt.o zip.o elf.o features.o btf_iter.o btf_relocate.o btf_sort.o
Loading
Loading