Skip to content

Commit f40bfd1

Browse files
eddyz87Alexei Starovoitov
authored andcommitted
selftests/bpf: fix bpf_loop_bench for new callback verification scheme
This is a preparatory change. A follow-up patch "bpf: verify callbacks as if they are called unknown number of times" changes logic for callbacks handling. While previously callbacks were verified as a single function call, new scheme takes into account that callbacks could be executed unknown number of times. This has dire implications for bpf_loop_bench: SEC("fentry/" SYS_PREFIX "sys_getpgid") int benchmark(void *ctx) { for (int i = 0; i < 1000; i++) { bpf_loop(nr_loops, empty_callback, NULL, 0); __sync_add_and_fetch(&hits, nr_loops); } return 0; } W/o callbacks change verifier sees it as a 1000 calls to empty_callback(). However, with callbacks change things become exponential: - i=0: state exploring empty_callback is scheduled with i=0 (a); - i=1: state exploring empty_callback is scheduled with i=1; ... - i=999: state exploring empty_callback is scheduled with i=999; - state (a) is popped from stack; - i=1: state exploring empty_callback is scheduled with i=1; ... Avoid this issue by rewriting outer loop as bpf_loop(). Unfortunately, this adds a function call to a loop at runtime, which negatively affects performance: throughput latency before: 149.919 ± 0.168 M ops/s, 6.670 ns/op after : 137.040 ± 0.187 M ops/s, 7.297 ns/op Acked-by: Andrii Nakryiko <andrii@kernel.org> Signed-off-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://lore.kernel.org/r/20231121020701.26440-4-eddyz87@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
1 parent 87eb015 commit f40bfd1

File tree

1 file changed

+8
-5
lines changed

1 file changed

+8
-5
lines changed

tools/testing/selftests/bpf/progs/bpf_loop_bench.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,16 @@ static int empty_callback(__u32 index, void *data)
1515
return 0;
1616
}
1717

18+
static int outer_loop(__u32 index, void *data)
19+
{
20+
bpf_loop(nr_loops, empty_callback, NULL, 0);
21+
__sync_add_and_fetch(&hits, nr_loops);
22+
return 0;
23+
}
24+
1825
SEC("fentry/" SYS_PREFIX "sys_getpgid")
1926
int benchmark(void *ctx)
2027
{
21-
for (int i = 0; i < 1000; i++) {
22-
bpf_loop(nr_loops, empty_callback, NULL, 0);
23-
24-
__sync_add_and_fetch(&hits, nr_loops);
25-
}
28+
bpf_loop(1000, outer_loop, NULL, 0);
2629
return 0;
2730
}

0 commit comments

Comments
 (0)