1 // SPDX-License-Identifier: GPL-2.0
3 #include <bpf/bpf_tracing.h>
4 #include <bpf/bpf_helpers.h>
5 #include "../bpf_testmod/bpf_testmod_kfunc.h"
8 struct prog_test_ref_kfunc __kptr *ptr;
12 __uint(type, BPF_MAP_TYPE_ARRAY);
14 __type(value, struct map_value);
15 __uint(max_entries, 16);
16 } array_map SEC(".maps");
18 static __noinline int cb1(void *map, void *key, void *value, void *ctx)
20 void *p = *(void **)ctx;
21 bpf_kfunc_call_test_release(p);
22 /* Without the fix this would cause underflow */
27 int underflow_prog(void *ctx)
29 struct prog_test_ref_kfunc *p;
32 p = bpf_kfunc_call_test_acquire(&sl);
35 bpf_for_each_map_elem(&array_map, cb1, &p, 0);
39 static __always_inline int cb2(void *map, void *key, void *value, void *ctx)
43 *(void **)ctx = bpf_kfunc_call_test_acquire(&sl);
44 /* Without the fix this would leak memory */
49 int leak_prog(void *ctx)
51 struct prog_test_ref_kfunc *p;
54 v = bpf_map_lookup_elem(&array_map, &(int){0});
59 bpf_for_each_map_elem(&array_map, cb2, &p, 0);
60 p = bpf_kptr_xchg(&v->ptr, p);
62 bpf_kfunc_call_test_release(p);
66 static __always_inline int cb(void *map, void *key, void *value, void *ctx)
71 static __always_inline int cb3(void *map, void *key, void *value, void *ctx)
76 bpf_kfunc_call_test_acquire(&sl);
77 bpf_for_each_map_elem(&array_map, cb, &p, 0);
78 /* It should only complain here, not in cb. This is why we need
79 * callback_ref to be set to frameno.
85 int nested_cb(void *ctx)
87 struct prog_test_ref_kfunc *p;
91 p = bpf_kfunc_call_test_acquire(&sl);
94 bpf_for_each_map_elem(&array_map, cb3, &sp, 0);
95 bpf_kfunc_call_test_release(p);
100 int non_cb_transfer_ref(void *ctx)
102 struct prog_test_ref_kfunc *p;
103 unsigned long sl = 0;
105 p = bpf_kfunc_call_test_acquire(&sl);
108 cb1(NULL, NULL, NULL, &p);
109 bpf_kfunc_call_test_acquire(&sl);
113 char _license[] SEC("license") = "GPL";