summaryrefslogtreecommitdiff
path: root/tools/testing/selftests/bpf/progs/bench_bpf_timing.bpf.h
blob: 6a1ad75f1fd70b6ac36e59baaebb24cc37994680 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (c) 2026 Meta Platforms, Inc. and affiliates. */

#ifndef __BENCH_BPF_TIMING_BPF_H__
#define __BENCH_BPF_TIMING_BPF_H__

#include <stdbool.h>
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
#include <bpf_may_goto.h>

#ifndef BENCH_NR_SAMPLES
#define BENCH_NR_SAMPLES	4096
#endif
#ifndef BENCH_NR_CPUS
#define BENCH_NR_CPUS		256
#endif
#define BENCH_CPU_MASK		(BENCH_NR_CPUS - 1)

__u64 timing_samples[BENCH_NR_CPUS][BENCH_NR_SAMPLES];
__u32 timing_idx[BENCH_NR_CPUS];

volatile __u32 batch_iters;
volatile __u32 timing_enabled;

static __always_inline void bench_record_sample(__u64 elapsed_ns)
{
	__u32 cpu, idx;

	if (!timing_enabled)
		return;

	cpu = bpf_get_smp_processor_id() & BENCH_CPU_MASK;
	idx = timing_idx[cpu];

	if (idx >= BENCH_NR_SAMPLES)
		return;

	timing_samples[cpu][idx] = elapsed_ns;
	timing_idx[cpu] = idx + 1;
}

/*
 * @body:  expression to time; return value (int) stored in __bench_result.
 * @reset: undo body's side-effects so each iteration starts identically.
 *         May reference __bench_result.  Use ({}) for empty reset.
 *
 * Runs batch_iters timed iterations, then one untimed iteration whose
 * return value the macro evaluates to (for validation).
 */
#define BENCH_BPF_LOOP(body, reset) ({					\
	__u64 __bench_start = bpf_ktime_get_ns();			\
	__u32 __bench_i;						\
	int __bench_result;						\
									\
	for (__bench_i = 0;						\
	     __bench_i < batch_iters && can_loop;			\
	     __bench_i++) {						\
		__bench_result = (body);				\
		reset;							\
	}								\
									\
	bench_record_sample(bpf_ktime_get_ns() - __bench_start);	\
									\
	__bench_result = (body);					\
	__bench_result;							\
})

#endif /* __BENCH_BPF_TIMING_BPF_H__ */