xref: /linux/tools/testing/selftests/bpf/progs/bench_bpf_timing.bpf.h (revision b2128290c29902315e632ea59e0504d6bc9e9b42)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /* Copyright (c) 2026 Meta Platforms, Inc. and affiliates. */
3 
4 #ifndef __BENCH_BPF_TIMING_BPF_H__
5 #define __BENCH_BPF_TIMING_BPF_H__
6 
7 #include <stdbool.h>
8 #include <linux/bpf.h>
9 #include <bpf/bpf_helpers.h>
10 #include <bpf_may_goto.h>
11 
12 #ifndef BENCH_NR_SAMPLES
13 #define BENCH_NR_SAMPLES	4096
14 #endif
15 #ifndef BENCH_NR_CPUS
16 #define BENCH_NR_CPUS		256
17 #endif
18 #define BENCH_CPU_MASK		(BENCH_NR_CPUS - 1)
19 
20 __u64 timing_samples[BENCH_NR_CPUS][BENCH_NR_SAMPLES];
21 __u32 timing_idx[BENCH_NR_CPUS];
22 
23 volatile __u32 batch_iters;
24 volatile __u32 timing_enabled;
25 
26 static __always_inline void bench_record_sample(__u64 elapsed_ns)
27 {
28 	__u32 cpu, idx;
29 
30 	if (!timing_enabled)
31 		return;
32 
33 	cpu = bpf_get_smp_processor_id() & BENCH_CPU_MASK;
34 	idx = timing_idx[cpu];
35 
36 	if (idx >= BENCH_NR_SAMPLES)
37 		return;
38 
39 	timing_samples[cpu][idx] = elapsed_ns;
40 	timing_idx[cpu] = idx + 1;
41 }
42 
43 /*
44  * @body:  expression to time; return value (int) stored in __bench_result.
45  * @reset: undo body's side-effects so each iteration starts identically.
46  *         May reference __bench_result.  Use ({}) for empty reset.
47  *
48  * Runs batch_iters timed iterations, then one untimed iteration whose
49  * return value the macro evaluates to (for validation).
50  */
51 #define BENCH_BPF_LOOP(body, reset) ({					\
52 	__u64 __bench_start = bpf_ktime_get_ns();			\
53 	__u32 __bench_i;						\
54 	int __bench_result;						\
55 									\
56 	for (__bench_i = 0;						\
57 	     __bench_i < batch_iters && can_loop;			\
58 	     __bench_i++) {						\
59 		__bench_result = (body);				\
60 		reset;							\
61 	}								\
62 									\
63 	bench_record_sample(bpf_ktime_get_ns() - __bench_start);	\
64 									\
65 	__bench_result = (body);					\
66 	__bench_result;							\
67 })
68 
69 #endif /* __BENCH_BPF_TIMING_BPF_H__ */
70