Context |
Check |
Description |
bpf/vmtest-bpf-next-VM_Test-13 |
success
|
Logs for s390x-gcc / GCC BPF
|
bpf/vmtest-bpf-next-VM_Test-18 |
success
|
Logs for s390x-gcc / test (test_verifier, false, 360) / test_verifier on s390x with gcc
|
bpf/vmtest-bpf-next-VM_Test-19 |
success
|
Logs for s390x-gcc / veristat-kernel
|
bpf/vmtest-bpf-next-VM_Test-20 |
success
|
Logs for s390x-gcc / veristat-meta
|
bpf/vmtest-bpf-next-VM_Test-21 |
success
|
Logs for set-matrix
|
bpf/vmtest-bpf-next-VM_Test-22 |
success
|
Logs for x86_64-gcc / GCC BPF / GCC BPF
|
bpf/vmtest-bpf-next-VM_Test-23 |
success
|
Logs for x86_64-gcc / build / build for x86_64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-24 |
success
|
Logs for x86_64-gcc / build-release
|
bpf/vmtest-bpf-next-VM_Test-25 |
success
|
Logs for x86_64-gcc / test (test_maps, false, 360) / test_maps on x86_64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-26 |
fail
|
Logs for x86_64-gcc / test (test_progs, false, 360) / test_progs on x86_64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-27 |
fail
|
Logs for x86_64-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-28 |
success
|
Logs for x86_64-gcc / test (test_progs_no_alu32_parallel, true, 30) / test_progs_no_alu32_parallel on x86_64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-29 |
success
|
Logs for x86_64-gcc / test (test_progs_parallel, true, 30) / test_progs_parallel on x86_64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-30 |
success
|
Logs for x86_64-gcc / test (test_verifier, false, 360) / test_verifier on x86_64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-31 |
success
|
Logs for x86_64-gcc / veristat-kernel / x86_64-gcc veristat_kernel
|
bpf/vmtest-bpf-next-VM_Test-32 |
success
|
Logs for x86_64-gcc / veristat-meta / x86_64-gcc veristat_meta
|
bpf/vmtest-bpf-next-VM_Test-33 |
success
|
Logs for x86_64-llvm-17 / GCC BPF / GCC BPF
|
bpf/vmtest-bpf-next-VM_Test-34 |
success
|
Logs for x86_64-llvm-17 / build / build for x86_64 with llvm-17
|
bpf/vmtest-bpf-next-VM_Test-35 |
success
|
Logs for x86_64-llvm-17 / build-release / build for x86_64 with llvm-17-O2
|
bpf/vmtest-bpf-next-VM_Test-36 |
success
|
Logs for x86_64-llvm-17 / test (test_maps, false, 360) / test_maps on x86_64 with llvm-17
|
bpf/vmtest-bpf-next-VM_Test-37 |
fail
|
Logs for x86_64-llvm-17 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-17
|
bpf/vmtest-bpf-next-VM_Test-38 |
fail
|
Logs for x86_64-llvm-17 / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with llvm-17
|
bpf/vmtest-bpf-next-VM_Test-39 |
success
|
Logs for x86_64-llvm-17 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-17
|
bpf/vmtest-bpf-next-VM_Test-40 |
success
|
Logs for x86_64-llvm-17 / veristat-kernel
|
bpf/vmtest-bpf-next-VM_Test-41 |
success
|
Logs for x86_64-llvm-17 / veristat-meta
|
bpf/vmtest-bpf-next-VM_Test-42 |
success
|
Logs for x86_64-llvm-18 / GCC BPF / GCC BPF
|
bpf/vmtest-bpf-next-VM_Test-43 |
success
|
Logs for x86_64-llvm-18 / build / build for x86_64 with llvm-18
|
bpf/vmtest-bpf-next-VM_Test-44 |
success
|
Logs for x86_64-llvm-18 / build-release / build for x86_64 with llvm-18-O2
|
bpf/vmtest-bpf-next-VM_Test-45 |
success
|
Logs for x86_64-llvm-18 / test (test_maps, false, 360) / test_maps on x86_64 with llvm-18
|
bpf/vmtest-bpf-next-VM_Test-46 |
fail
|
Logs for x86_64-llvm-18 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-18
|
bpf/vmtest-bpf-next-VM_Test-47 |
fail
|
Logs for x86_64-llvm-18 / test (test_progs_cpuv4, false, 360) / test_progs_cpuv4 on x86_64 with llvm-18
|
bpf/vmtest-bpf-next-VM_Test-48 |
fail
|
Logs for x86_64-llvm-18 / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with llvm-18
|
bpf/vmtest-bpf-next-VM_Test-49 |
success
|
Logs for x86_64-llvm-18 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-18
|
bpf/vmtest-bpf-next-VM_Test-50 |
success
|
Logs for x86_64-llvm-18 / veristat-kernel
|
bpf/vmtest-bpf-next-VM_Test-51 |
success
|
Logs for x86_64-llvm-18 / veristat-meta
|
bpf/vmtest-bpf-next-VM_Test-9 |
success
|
Logs for aarch64-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on aarch64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-16 |
success
|
Logs for s390x-gcc / test (test_progs, false, 360) / test_progs on s390x with gcc
|
bpf/vmtest-bpf-next-PR |
success
|
PR summary
|
bpf/vmtest-bpf-next-VM_Test-0 |
success
|
Logs for Lint
|
bpf/vmtest-bpf-next-VM_Test-1 |
success
|
Logs for ShellCheck
|
bpf/vmtest-bpf-next-VM_Test-2 |
success
|
Logs for Unittests
|
bpf/vmtest-bpf-next-VM_Test-3 |
success
|
Logs for Validate matrix.py
|
bpf/vmtest-bpf-next-VM_Test-7 |
success
|
Logs for s390x-gcc / build-release
|
bpf/vmtest-bpf-next-VM_Test-8 |
success
|
Logs for set-matrix
|
bpf/vmtest-bpf-next-VM_Test-10 |
success
|
Logs for x86_64-gcc / build-release
|
bpf/vmtest-bpf-next-VM_Test-4 |
success
|
Logs for aarch64-gcc / GCC BPF
|
bpf/vmtest-bpf-next-VM_Test-5 |
success
|
Logs for aarch64-gcc / build / build for aarch64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-6 |
success
|
Logs for aarch64-gcc / build-release
|
bpf/vmtest-bpf-next-VM_Test-11 |
success
|
Logs for aarch64-gcc / veristat-kernel
|
bpf/vmtest-bpf-next-VM_Test-12 |
success
|
Logs for aarch64-gcc / veristat-meta
|
bpf/vmtest-bpf-next-VM_Test-14 |
success
|
Logs for s390x-gcc / build-release
|
bpf/vmtest-bpf-next-VM_Test-15 |
success
|
Logs for set-matrix
|
bpf/vmtest-bpf-next-VM_Test-17 |
success
|
Logs for x86_64-gcc / build-release
|
netdev/series_format |
success
|
Posting correctly formatted
|
netdev/tree_selection |
success
|
Clearly marked for bpf-next, async
|
netdev/ynl |
success
|
Generated files up to date;
no warnings/errors;
no diff in generated;
|
netdev/fixes_present |
success
|
Fixes tag not required for -next series
|
netdev/header_inline |
success
|
No static functions without inline keyword in header files
|
netdev/build_32bit |
success
|
Errors and warnings before: 0 this patch: 0
|
netdev/build_tools |
success
|
No tools touched, skip
|
netdev/cc_maintainers |
success
|
CCed 13 of 13 maintainers
|
netdev/build_clang |
success
|
Errors and warnings before: 6 this patch: 6
|
netdev/verify_signedoff |
success
|
Signed-off-by tag matches author and committer
|
netdev/deprecated_api |
success
|
None detected
|
netdev/check_selftest |
success
|
No net selftest shell script
|
netdev/verify_fixes |
success
|
No Fixes tag
|
netdev/build_allmodconfig_warn |
success
|
Errors and warnings before: 2 this patch: 2
|
netdev/checkpatch |
warning
|
WARNING: line length of 82 exceeds 80 columns
WARNING: line length of 83 exceeds 80 columns
WARNING: line length of 84 exceeds 80 columns
WARNING: line length of 86 exceeds 80 columns
WARNING: line length of 88 exceeds 80 columns
WARNING: line length of 90 exceeds 80 columns
WARNING: line length of 92 exceeds 80 columns
WARNING: line length of 93 exceeds 80 columns
WARNING: line length of 94 exceeds 80 columns
WARNING: line length of 95 exceeds 80 columns
WARNING: line length of 96 exceeds 80 columns
WARNING: line length of 97 exceeds 80 columns
WARNING: line length of 98 exceeds 80 columns
|
netdev/build_clang_rust |
success
|
No Rust files in patch. Skipping build
|
netdev/kdoc |
success
|
Errors and warnings before: 0 this patch: 0
|
netdev/source_inline |
fail
|
Was 0 now: 1
|
@@ -249,6 +249,17 @@ struct btf_struct_ops_tab {
struct bpf_struct_ops_desc ops[];
};
+struct btf_struct_kfunc {
+ u32 struct_btf_id;
+ unsigned long kfunc_addr;
+};
+
+struct btf_struct_kfunc_tab {
+ u32 cnt;
+ u32 capacity;
+ struct btf_struct_kfunc *set;
+};
+
struct btf {
void *data;
struct btf_type **types;
@@ -267,6 +278,9 @@ struct btf {
struct btf_id_dtor_kfunc_tab *dtor_kfunc_tab;
struct btf_struct_metas *struct_meta_tab;
struct btf_struct_ops_tab *struct_ops_tab;
+ struct btf_struct_kfunc_tab *acquire_kfunc_tab;
+ struct btf_struct_kfunc_tab *release_kfunc_tab;
+ struct btf_struct_kfunc_tab *release_kfunc_btf_tab;
/* split BTF support */
struct btf *base_btf;
@@ -8357,6 +8371,112 @@ static int btf_check_kfunc_protos(struct btf *btf, u32 func_id, u32 func_flags)
return 0;
}
+static inline int btf_kfunc_addr_cmp_func(const void *a, const void *b)
+{
+ const struct btf_struct_kfunc *pa = a, *pb = b;
+
+ return pa->kfunc_addr - pb->kfunc_addr;
+}
+
+static int __btf_struct_kfunc_set_add(struct btf_struct_kfunc_tab **kfunc_tab, u32 struct_btf_id,
+ unsigned long kfunc_addr, void *key, cmp_func_t cmp_func)
+{
+ struct btf_struct_kfunc_tab *tab;
+ struct btf_struct_kfunc *set;
+ int ret;
+
+ tab = *kfunc_tab;
+ if (!tab) {
+ tab = kzalloc(sizeof(*tab), GFP_KERNEL | __GFP_NOWARN);
+ if (!tab)
+ return -ENOMEM;
+
+ tab->cnt = 0;
+ tab->capacity = 0;
+
+ *kfunc_tab = tab;
+ }
+
+ set = tab->set;
+ if (set && bsearch(key, set, tab->cnt, sizeof(struct btf_struct_kfunc), cmp_func))
+ return 0;
+
+ if (tab->cnt + 1 > tab->capacity) {
+ set = krealloc(tab->set, sizeof(struct btf_struct_kfunc) * (tab->capacity + 16),
+ GFP_KERNEL | __GFP_NOWARN);
+ if (!set) {
+ ret = -ENOMEM;
+ goto end;
+ }
+ tab->capacity += 16;
+ }
+
+ set[tab->cnt].struct_btf_id = struct_btf_id;
+ set[tab->cnt].kfunc_addr = kfunc_addr;
+
+ tab->set = set;
+ tab->cnt += 1;
+
+ sort(tab->set, tab->cnt, sizeof(struct btf_struct_kfunc), cmp_func, NULL);
+
+ return 0;
+end:
+ kfree(tab->set);
+ kfree(tab);
+ return ret;
+}
+
+static int btf_struct_kfunc_set_add(struct btf *btf, u32 kfunc_id, u32 kfunc_flags)
+{
+ const struct btf_type *kfunc, *kfunc_proto, *sturct_type;
+ struct btf_struct_kfunc dummy_key;
+ unsigned long kfunc_addr;
+ const char *kfunc_name;
+ u32 struct_btf_id;
+ int ret;
+
+ kfunc = btf_type_by_id(btf, kfunc_id);
+ kfunc_name = btf_name_by_offset(btf, kfunc->name_off);
+ if (!kfunc_name)
+ return -EINVAL;
+
+ kfunc_proto = btf_type_by_id(btf, kfunc->type);
+ if (!kfunc_proto || !btf_type_is_func_proto(kfunc_proto))
+ return -EINVAL;
+
+ if (kfunc_flags & KF_ACQUIRE) {
+ sturct_type = btf_type_skip_modifiers(btf, kfunc_proto->type, NULL);
+ } else { /* kfunc_flags & KF_RELEASE */
+ if (btf_type_vlen(kfunc_proto) < 1)
+ return -EINVAL;
+
+ sturct_type = btf_type_skip_modifiers(btf, btf_params(kfunc_proto)[0].type, NULL);
+ }
+
+ if (!sturct_type || !btf_type_is_ptr(sturct_type))
+ return -EINVAL;
+ sturct_type = btf_type_skip_modifiers(btf, sturct_type->type, &struct_btf_id);
+ if (!sturct_type || !__btf_type_is_struct(sturct_type))
+ return -EINVAL;
+
+ kfunc_addr = kallsyms_lookup_name(kfunc_name);
+ dummy_key.kfunc_addr = kfunc_addr;
+
+ if (kfunc_flags & KF_ACQUIRE) {
+ ret = __btf_struct_kfunc_set_add(&btf->acquire_kfunc_tab, struct_btf_id,
+ kfunc_addr, &dummy_key, btf_kfunc_addr_cmp_func);
+ } else { /* kfunc_flags & KF_RELEASE */
+ ret = __btf_struct_kfunc_set_add(&btf->release_kfunc_tab, struct_btf_id,
+ kfunc_addr, &dummy_key, btf_kfunc_addr_cmp_func);
+ if (ret)
+ return ret;
+ ret = __btf_struct_kfunc_set_add(&btf->release_kfunc_btf_tab, struct_btf_id,
+ kfunc_addr, &struct_btf_id, btf_id_cmp_func);
+ }
+
+ return ret;
+}
+
/* Kernel Function (kfunc) BTF ID set registration API */
static int btf_populate_kfunc_set(struct btf *btf, enum btf_kfunc_hook hook,
@@ -8453,9 +8573,13 @@ static int btf_populate_kfunc_set(struct btf *btf, enum btf_kfunc_hook hook,
/* Concatenate the two sets */
memcpy(set->pairs + set->cnt, add_set->pairs, add_set->cnt * sizeof(set->pairs[0]));
/* Now that the set is copied, update with relocated BTF ids */
- for (i = set->cnt; i < set->cnt + add_set->cnt; i++)
+ for (i = set->cnt; i < set->cnt + add_set->cnt; i++) {
set->pairs[i].id = btf_relocate_id(btf, set->pairs[i].id);
+ if (set->pairs[i].flags & (KF_ACQUIRE | KF_RELEASE))
+ btf_struct_kfunc_set_add(btf, set->pairs[i].id, set->pairs[i].flags);
+ }
+
set->cnt += add_set->cnt;
sort(set->pairs, set->cnt, sizeof(set->pairs[0]), btf_id_cmp_func, NULL);
This patch pairs data structure types with corresponding acquire/release kfuncs. Currently all kfuncs with KF_ACQUIRE have only one return value, and all kfuncs with KF_RELEASE have only one argument, so we can pair kfuncs with the btf id of the data structure type that can be acquired/released to construct tables. btf_struct_kfunc_set_add is used to add kfunc to acquire_kfunc_tab or release_kfunc_tab/release_kfunc_btf_tab depending on whether kfuncs is acquired or released, where the data structure type is converted to btf id and the kfunc name is converted to the memory address of kfunc. For acquiring kfuncs, we only need a table acquire_kfunc_tab, the kfuncs memory address is used as a key to find the type of the acquired object based on kfuncs when acquiring a reference. For releasing kfuncs, we need two tables release_kfunc_tab/ release_kfunc_btf_tab. In release_kfunc_btf_tab, the btf id is used as the key to find the kfunc that can be used to release the object according to the type of the object when the object needs to be released. In release_kfunc_tab, the kfuncs memory address is used as the key. Currently, release_kfunc_tab is only used to determine whether a kfunc is a releasing kfunc. Signed-off-by: Juntong Deng <juntong.deng@outlook.com> --- kernel/bpf/btf.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 125 insertions(+), 1 deletion(-)