1*5cb481e1SKumar Kartikeya Dwivedi // SPDX-License-Identifier: GPL-2.0
2*5cb481e1SKumar Kartikeya Dwivedi
3*5cb481e1SKumar Kartikeya Dwivedi #include <vmlinux.h>
4*5cb481e1SKumar Kartikeya Dwivedi #include <bpf/bpf_helpers.h>
5*5cb481e1SKumar Kartikeya Dwivedi #include "bpf_misc.h"
6*5cb481e1SKumar Kartikeya Dwivedi
7*5cb481e1SKumar Kartikeya Dwivedi struct timer_value {
8*5cb481e1SKumar Kartikeya Dwivedi struct bpf_timer timer;
9*5cb481e1SKumar Kartikeya Dwivedi };
10*5cb481e1SKumar Kartikeya Dwivedi
11*5cb481e1SKumar Kartikeya Dwivedi struct {
12*5cb481e1SKumar Kartikeya Dwivedi __uint(type, BPF_MAP_TYPE_ARRAY);
13*5cb481e1SKumar Kartikeya Dwivedi __uint(max_entries, 1);
14*5cb481e1SKumar Kartikeya Dwivedi __type(key, __u32);
15*5cb481e1SKumar Kartikeya Dwivedi __type(value, struct timer_value);
16*5cb481e1SKumar Kartikeya Dwivedi } timer_map SEC(".maps");
17*5cb481e1SKumar Kartikeya Dwivedi
18*5cb481e1SKumar Kartikeya Dwivedi SEC("?raw_tp")
19*5cb481e1SKumar Kartikeya Dwivedi __success __log_level(4)
20*5cb481e1SKumar Kartikeya Dwivedi __msg("subprog 0 (stats_main_only) main insns_self 2 insns_total 2 stack 0")
21*5cb481e1SKumar Kartikeya Dwivedi __msg("processed 2 insns")
stats_main_only(void)22*5cb481e1SKumar Kartikeya Dwivedi __naked int stats_main_only(void)
23*5cb481e1SKumar Kartikeya Dwivedi {
24*5cb481e1SKumar Kartikeya Dwivedi asm volatile (
25*5cb481e1SKumar Kartikeya Dwivedi "r0 = 0;"
26*5cb481e1SKumar Kartikeya Dwivedi "exit;"
27*5cb481e1SKumar Kartikeya Dwivedi );
28*5cb481e1SKumar Kartikeya Dwivedi }
29*5cb481e1SKumar Kartikeya Dwivedi
30*5cb481e1SKumar Kartikeya Dwivedi __naked __noinline __used
stats_chain_leaf(void)31*5cb481e1SKumar Kartikeya Dwivedi static int stats_chain_leaf(void)
32*5cb481e1SKumar Kartikeya Dwivedi {
33*5cb481e1SKumar Kartikeya Dwivedi asm volatile (
34*5cb481e1SKumar Kartikeya Dwivedi "r0 = 0;"
35*5cb481e1SKumar Kartikeya Dwivedi "exit;"
36*5cb481e1SKumar Kartikeya Dwivedi );
37*5cb481e1SKumar Kartikeya Dwivedi }
38*5cb481e1SKumar Kartikeya Dwivedi
39*5cb481e1SKumar Kartikeya Dwivedi __naked __noinline __used
stats_chain_parent(void)40*5cb481e1SKumar Kartikeya Dwivedi static int stats_chain_parent(void)
41*5cb481e1SKumar Kartikeya Dwivedi {
42*5cb481e1SKumar Kartikeya Dwivedi asm volatile (
43*5cb481e1SKumar Kartikeya Dwivedi "call stats_chain_leaf;"
44*5cb481e1SKumar Kartikeya Dwivedi "exit;"
45*5cb481e1SKumar Kartikeya Dwivedi );
46*5cb481e1SKumar Kartikeya Dwivedi }
47*5cb481e1SKumar Kartikeya Dwivedi
48*5cb481e1SKumar Kartikeya Dwivedi SEC("?raw_tp")
49*5cb481e1SKumar Kartikeya Dwivedi __success __log_level(4)
50*5cb481e1SKumar Kartikeya Dwivedi /*
51*5cb481e1SKumar Kartikeya Dwivedi * self: 2 + 2 + 2 = 6
52*5cb481e1SKumar Kartikeya Dwivedi * totals: leaf 2, parent 2 + 2 = 4, main 2 + 4 = 6
53*5cb481e1SKumar Kartikeya Dwivedi */
54*5cb481e1SKumar Kartikeya Dwivedi __msg("subprog 0 (stats_static_chain) main insns_self 2 insns_total 6 stack 0")
55*5cb481e1SKumar Kartikeya Dwivedi __msg("subprog {{[0-9]+}} (stats_chain_parent) static insns_self 2 insns_total 4 stack 0")
56*5cb481e1SKumar Kartikeya Dwivedi __msg("subprog {{[0-9]+}} (stats_chain_leaf) static insns_self 2 insns_total 2 stack 0")
57*5cb481e1SKumar Kartikeya Dwivedi __msg("processed 6 insns")
stats_static_chain(void)58*5cb481e1SKumar Kartikeya Dwivedi __naked int stats_static_chain(void)
59*5cb481e1SKumar Kartikeya Dwivedi {
60*5cb481e1SKumar Kartikeya Dwivedi asm volatile (
61*5cb481e1SKumar Kartikeya Dwivedi "call stats_chain_parent;"
62*5cb481e1SKumar Kartikeya Dwivedi "exit;"
63*5cb481e1SKumar Kartikeya Dwivedi );
64*5cb481e1SKumar Kartikeya Dwivedi }
65*5cb481e1SKumar Kartikeya Dwivedi
66*5cb481e1SKumar Kartikeya Dwivedi __naked __noinline __used
stats_shared_leaf(void)67*5cb481e1SKumar Kartikeya Dwivedi static int stats_shared_leaf(void)
68*5cb481e1SKumar Kartikeya Dwivedi {
69*5cb481e1SKumar Kartikeya Dwivedi asm volatile (
70*5cb481e1SKumar Kartikeya Dwivedi "r0 = 0;"
71*5cb481e1SKumar Kartikeya Dwivedi "exit;"
72*5cb481e1SKumar Kartikeya Dwivedi );
73*5cb481e1SKumar Kartikeya Dwivedi }
74*5cb481e1SKumar Kartikeya Dwivedi
75*5cb481e1SKumar Kartikeya Dwivedi __naked __noinline __used
stats_global_root(void)76*5cb481e1SKumar Kartikeya Dwivedi int stats_global_root(void)
77*5cb481e1SKumar Kartikeya Dwivedi {
78*5cb481e1SKumar Kartikeya Dwivedi asm volatile (
79*5cb481e1SKumar Kartikeya Dwivedi "call stats_shared_leaf;"
80*5cb481e1SKumar Kartikeya Dwivedi "exit;"
81*5cb481e1SKumar Kartikeya Dwivedi );
82*5cb481e1SKumar Kartikeya Dwivedi }
83*5cb481e1SKumar Kartikeya Dwivedi
84*5cb481e1SKumar Kartikeya Dwivedi SEC("?raw_tp")
85*5cb481e1SKumar Kartikeya Dwivedi __success __log_level(4)
86*5cb481e1SKumar Kartikeya Dwivedi /*
87*5cb481e1SKumar Kartikeya Dwivedi * stats_shared_leaf is explored once under each independent root.
88*5cb481e1SKumar Kartikeya Dwivedi * self: main 3 + leaf 4 + global 2 = 9
89*5cb481e1SKumar Kartikeya Dwivedi * root totals: main 5 + global 4 = 9
90*5cb481e1SKumar Kartikeya Dwivedi */
91*5cb481e1SKumar Kartikeya Dwivedi __msg("subprog 0 (stats_shared_roots) main insns_self 3 insns_total 5 stack 0")
92*5cb481e1SKumar Kartikeya Dwivedi __msg("subprog {{[0-9]+}} (stats_shared_leaf) static insns_self 4 insns_total 4 stack 0")
93*5cb481e1SKumar Kartikeya Dwivedi __msg("subprog {{[0-9]+}} (stats_global_root) global insns_self 2 insns_total 4 stack 0")
94*5cb481e1SKumar Kartikeya Dwivedi __msg("processed 9 insns")
stats_shared_roots(void)95*5cb481e1SKumar Kartikeya Dwivedi __naked int stats_shared_roots(void)
96*5cb481e1SKumar Kartikeya Dwivedi {
97*5cb481e1SKumar Kartikeya Dwivedi asm volatile (
98*5cb481e1SKumar Kartikeya Dwivedi "call stats_shared_leaf;"
99*5cb481e1SKumar Kartikeya Dwivedi "call stats_global_root;"
100*5cb481e1SKumar Kartikeya Dwivedi "exit;"
101*5cb481e1SKumar Kartikeya Dwivedi );
102*5cb481e1SKumar Kartikeya Dwivedi }
103*5cb481e1SKumar Kartikeya Dwivedi
104*5cb481e1SKumar Kartikeya Dwivedi __noinline __used
stats_async_leaf(void * map,__u32 * key,struct bpf_timer * timer)105*5cb481e1SKumar Kartikeya Dwivedi static int stats_async_leaf(void *map, __u32 *key, struct bpf_timer *timer)
106*5cb481e1SKumar Kartikeya Dwivedi {
107*5cb481e1SKumar Kartikeya Dwivedi return 0;
108*5cb481e1SKumar Kartikeya Dwivedi }
109*5cb481e1SKumar Kartikeya Dwivedi
110*5cb481e1SKumar Kartikeya Dwivedi __noinline __used
stats_async_schedule(struct bpf_map * map,__u32 * key,struct timer_value * value,void * ctx)111*5cb481e1SKumar Kartikeya Dwivedi static __u64 stats_async_schedule(struct bpf_map *map, __u32 *key,
112*5cb481e1SKumar Kartikeya Dwivedi struct timer_value *value, void *ctx)
113*5cb481e1SKumar Kartikeya Dwivedi {
114*5cb481e1SKumar Kartikeya Dwivedi asm volatile (
115*5cb481e1SKumar Kartikeya Dwivedi "r1 = %[timer];"
116*5cb481e1SKumar Kartikeya Dwivedi "r2 = %[stats_async_leaf];"
117*5cb481e1SKumar Kartikeya Dwivedi "call %[bpf_timer_set_callback];"
118*5cb481e1SKumar Kartikeya Dwivedi :
119*5cb481e1SKumar Kartikeya Dwivedi : [timer] "r" (value),
120*5cb481e1SKumar Kartikeya Dwivedi __imm_ptr(stats_async_leaf),
121*5cb481e1SKumar Kartikeya Dwivedi __imm(bpf_timer_set_callback)
122*5cb481e1SKumar Kartikeya Dwivedi : __clobber_common
123*5cb481e1SKumar Kartikeya Dwivedi );
124*5cb481e1SKumar Kartikeya Dwivedi return 0;
125*5cb481e1SKumar Kartikeya Dwivedi }
126*5cb481e1SKumar Kartikeya Dwivedi
127*5cb481e1SKumar Kartikeya Dwivedi SEC("?raw_tp")
128*5cb481e1SKumar Kartikeya Dwivedi __success __log_level(4)
129*5cb481e1SKumar Kartikeya Dwivedi /*
130*5cb481e1SKumar Kartikeya Dwivedi * self: 9 + 7 + 2 = 18
131*5cb481e1SKumar Kartikeya Dwivedi * totals: leaf 2, scheduler 7, main root 18
132*5cb481e1SKumar Kartikeya Dwivedi */
133*5cb481e1SKumar Kartikeya Dwivedi __msg("subprog 0 (stats_async_direct) main insns_self 9 insns_total 18 stack 0")
134*5cb481e1SKumar Kartikeya Dwivedi __msg("subprog {{[0-9]+}} (stats_async_schedule) static insns_self 7 insns_total 7 stack 0")
135*5cb481e1SKumar Kartikeya Dwivedi __msg("subprog {{[0-9]+}} (stats_async_leaf) static insns_self 2 insns_total 2 stack 0")
136*5cb481e1SKumar Kartikeya Dwivedi __msg("processed 18 insns")
stats_async_direct(void)137*5cb481e1SKumar Kartikeya Dwivedi __naked int stats_async_direct(void)
138*5cb481e1SKumar Kartikeya Dwivedi {
139*5cb481e1SKumar Kartikeya Dwivedi asm volatile (
140*5cb481e1SKumar Kartikeya Dwivedi "r1 = %[timer_map] ll;"
141*5cb481e1SKumar Kartikeya Dwivedi "r2 = %[stats_async_schedule];"
142*5cb481e1SKumar Kartikeya Dwivedi "r3 = 0;"
143*5cb481e1SKumar Kartikeya Dwivedi "r4 = 0;"
144*5cb481e1SKumar Kartikeya Dwivedi "call %[bpf_for_each_map_elem];"
145*5cb481e1SKumar Kartikeya Dwivedi "r0 = 0;"
146*5cb481e1SKumar Kartikeya Dwivedi "exit;"
147*5cb481e1SKumar Kartikeya Dwivedi :
148*5cb481e1SKumar Kartikeya Dwivedi : __imm_addr(timer_map),
149*5cb481e1SKumar Kartikeya Dwivedi __imm_ptr(stats_async_schedule),
150*5cb481e1SKumar Kartikeya Dwivedi __imm(bpf_for_each_map_elem)
151*5cb481e1SKumar Kartikeya Dwivedi : __clobber_common
152*5cb481e1SKumar Kartikeya Dwivedi );
153*5cb481e1SKumar Kartikeya Dwivedi }
154*5cb481e1SKumar Kartikeya Dwivedi
155*5cb481e1SKumar Kartikeya Dwivedi __noinline __used
stats_async_nested_leaf(void * map,__u32 * key,struct bpf_timer * timer)156*5cb481e1SKumar Kartikeya Dwivedi static int stats_async_nested_leaf(void *map, __u32 *key, struct bpf_timer *timer)
157*5cb481e1SKumar Kartikeya Dwivedi {
158*5cb481e1SKumar Kartikeya Dwivedi return 0;
159*5cb481e1SKumar Kartikeya Dwivedi }
160*5cb481e1SKumar Kartikeya Dwivedi
161*5cb481e1SKumar Kartikeya Dwivedi __noinline __used
stats_async_outer(void * map,__u32 * key,struct bpf_timer * timer)162*5cb481e1SKumar Kartikeya Dwivedi static int stats_async_outer(void *map, __u32 *key, struct bpf_timer *timer)
163*5cb481e1SKumar Kartikeya Dwivedi {
164*5cb481e1SKumar Kartikeya Dwivedi asm volatile (
165*5cb481e1SKumar Kartikeya Dwivedi "r1 = %[timer];"
166*5cb481e1SKumar Kartikeya Dwivedi "r2 = %[stats_async_nested_leaf];"
167*5cb481e1SKumar Kartikeya Dwivedi "call %[bpf_timer_set_callback];"
168*5cb481e1SKumar Kartikeya Dwivedi :
169*5cb481e1SKumar Kartikeya Dwivedi : [timer] "r" (timer),
170*5cb481e1SKumar Kartikeya Dwivedi __imm_ptr(stats_async_nested_leaf),
171*5cb481e1SKumar Kartikeya Dwivedi __imm(bpf_timer_set_callback)
172*5cb481e1SKumar Kartikeya Dwivedi : __clobber_common
173*5cb481e1SKumar Kartikeya Dwivedi );
174*5cb481e1SKumar Kartikeya Dwivedi return 0;
175*5cb481e1SKumar Kartikeya Dwivedi }
176*5cb481e1SKumar Kartikeya Dwivedi
177*5cb481e1SKumar Kartikeya Dwivedi __noinline __used
stats_async_nested_schedule(struct bpf_map * map,__u32 * key,struct timer_value * value,void * ctx)178*5cb481e1SKumar Kartikeya Dwivedi static __u64 stats_async_nested_schedule(struct bpf_map *map, __u32 *key,
179*5cb481e1SKumar Kartikeya Dwivedi struct timer_value *value, void *ctx)
180*5cb481e1SKumar Kartikeya Dwivedi {
181*5cb481e1SKumar Kartikeya Dwivedi asm volatile (
182*5cb481e1SKumar Kartikeya Dwivedi "r1 = %[timer];"
183*5cb481e1SKumar Kartikeya Dwivedi "r2 = %[stats_async_outer];"
184*5cb481e1SKumar Kartikeya Dwivedi "call %[bpf_timer_set_callback];"
185*5cb481e1SKumar Kartikeya Dwivedi :
186*5cb481e1SKumar Kartikeya Dwivedi : [timer] "r" (value),
187*5cb481e1SKumar Kartikeya Dwivedi __imm_ptr(stats_async_outer),
188*5cb481e1SKumar Kartikeya Dwivedi __imm(bpf_timer_set_callback)
189*5cb481e1SKumar Kartikeya Dwivedi : __clobber_common
190*5cb481e1SKumar Kartikeya Dwivedi );
191*5cb481e1SKumar Kartikeya Dwivedi return 0;
192*5cb481e1SKumar Kartikeya Dwivedi }
193*5cb481e1SKumar Kartikeya Dwivedi
194*5cb481e1SKumar Kartikeya Dwivedi SEC("?raw_tp")
195*5cb481e1SKumar Kartikeya Dwivedi __success __log_level(4)
196*5cb481e1SKumar Kartikeya Dwivedi /*
197*5cb481e1SKumar Kartikeya Dwivedi * self: 9 + 7 + 7 + 2 = 25
198*5cb481e1SKumar Kartikeya Dwivedi * totals: leaf 2, outer 7, scheduler 7, main root 25
199*5cb481e1SKumar Kartikeya Dwivedi */
200*5cb481e1SKumar Kartikeya Dwivedi __msg("subprog 0 (stats_async_nested) main insns_self 9 insns_total 25 stack 0")
201*5cb481e1SKumar Kartikeya Dwivedi __msg("subprog {{[0-9]+}} (stats_async_nested_schedule) static insns_self 7 insns_total 7 stack 0")
202*5cb481e1SKumar Kartikeya Dwivedi __msg("subprog {{[0-9]+}} (stats_async_outer) static insns_self 7 insns_total 7 stack 0")
203*5cb481e1SKumar Kartikeya Dwivedi __msg("subprog {{[0-9]+}} (stats_async_nested_leaf) static insns_self 2 insns_total 2 stack 0")
204*5cb481e1SKumar Kartikeya Dwivedi __msg("processed 25 insns")
stats_async_nested(void)205*5cb481e1SKumar Kartikeya Dwivedi __naked int stats_async_nested(void)
206*5cb481e1SKumar Kartikeya Dwivedi {
207*5cb481e1SKumar Kartikeya Dwivedi asm volatile (
208*5cb481e1SKumar Kartikeya Dwivedi "r1 = %[timer_map] ll;"
209*5cb481e1SKumar Kartikeya Dwivedi "r2 = %[stats_async_nested_schedule];"
210*5cb481e1SKumar Kartikeya Dwivedi "r3 = 0;"
211*5cb481e1SKumar Kartikeya Dwivedi "r4 = 0;"
212*5cb481e1SKumar Kartikeya Dwivedi "call %[bpf_for_each_map_elem];"
213*5cb481e1SKumar Kartikeya Dwivedi "r0 = 0;"
214*5cb481e1SKumar Kartikeya Dwivedi "exit;"
215*5cb481e1SKumar Kartikeya Dwivedi :
216*5cb481e1SKumar Kartikeya Dwivedi : __imm_addr(timer_map),
217*5cb481e1SKumar Kartikeya Dwivedi __imm_ptr(stats_async_nested_schedule),
218*5cb481e1SKumar Kartikeya Dwivedi __imm(bpf_for_each_map_elem)
219*5cb481e1SKumar Kartikeya Dwivedi : __clobber_common
220*5cb481e1SKumar Kartikeya Dwivedi );
221*5cb481e1SKumar Kartikeya Dwivedi }
222*5cb481e1SKumar Kartikeya Dwivedi
223*5cb481e1SKumar Kartikeya Dwivedi char _license[] SEC("license") = "GPL";
224