xref: /OK3568_Linux_fs/kernel/tools/testing/selftests/bpf/bench.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun #pragma once
3*4882a593Smuzhiyun #include <stdlib.h>
4*4882a593Smuzhiyun #include <stdbool.h>
5*4882a593Smuzhiyun #include <linux/err.h>
6*4882a593Smuzhiyun #include <errno.h>
7*4882a593Smuzhiyun #include <unistd.h>
8*4882a593Smuzhiyun #include <bpf/bpf.h>
9*4882a593Smuzhiyun #include <bpf/libbpf.h>
10*4882a593Smuzhiyun #include <math.h>
11*4882a593Smuzhiyun #include <time.h>
12*4882a593Smuzhiyun #include <sys/syscall.h>
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun struct cpu_set {
15*4882a593Smuzhiyun 	bool *cpus;
16*4882a593Smuzhiyun 	int cpus_len;
17*4882a593Smuzhiyun 	int next_cpu;
18*4882a593Smuzhiyun };
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun struct env {
21*4882a593Smuzhiyun 	char *bench_name;
22*4882a593Smuzhiyun 	int duration_sec;
23*4882a593Smuzhiyun 	int warmup_sec;
24*4882a593Smuzhiyun 	bool verbose;
25*4882a593Smuzhiyun 	bool list;
26*4882a593Smuzhiyun 	bool affinity;
27*4882a593Smuzhiyun 	int consumer_cnt;
28*4882a593Smuzhiyun 	int producer_cnt;
29*4882a593Smuzhiyun 	struct cpu_set prod_cpus;
30*4882a593Smuzhiyun 	struct cpu_set cons_cpus;
31*4882a593Smuzhiyun };
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun struct bench_res {
34*4882a593Smuzhiyun 	long hits;
35*4882a593Smuzhiyun 	long drops;
36*4882a593Smuzhiyun };
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun struct bench {
39*4882a593Smuzhiyun 	const char *name;
40*4882a593Smuzhiyun 	void (*validate)();
41*4882a593Smuzhiyun 	void (*setup)();
42*4882a593Smuzhiyun 	void *(*producer_thread)(void *ctx);
43*4882a593Smuzhiyun 	void *(*consumer_thread)(void *ctx);
44*4882a593Smuzhiyun 	void (*measure)(struct bench_res* res);
45*4882a593Smuzhiyun 	void (*report_progress)(int iter, struct bench_res* res, long delta_ns);
46*4882a593Smuzhiyun 	void (*report_final)(struct bench_res res[], int res_cnt);
47*4882a593Smuzhiyun };
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun struct counter {
50*4882a593Smuzhiyun 	long value;
51*4882a593Smuzhiyun } __attribute__((aligned(128)));
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun extern struct env env;
54*4882a593Smuzhiyun extern const struct bench *bench;
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun void setup_libbpf();
57*4882a593Smuzhiyun void hits_drops_report_progress(int iter, struct bench_res *res, long delta_ns);
58*4882a593Smuzhiyun void hits_drops_report_final(struct bench_res res[], int res_cnt);
59*4882a593Smuzhiyun 
get_time_ns()60*4882a593Smuzhiyun static inline __u64 get_time_ns() {
61*4882a593Smuzhiyun 	struct timespec t;
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun 	clock_gettime(CLOCK_MONOTONIC, &t);
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun 	return (u64)t.tv_sec * 1000000000 + t.tv_nsec;
66*4882a593Smuzhiyun }
67*4882a593Smuzhiyun 
atomic_inc(long * value)68*4882a593Smuzhiyun static inline void atomic_inc(long *value)
69*4882a593Smuzhiyun {
70*4882a593Smuzhiyun 	(void)__atomic_add_fetch(value, 1, __ATOMIC_RELAXED);
71*4882a593Smuzhiyun }
72*4882a593Smuzhiyun 
atomic_add(long * value,long n)73*4882a593Smuzhiyun static inline void atomic_add(long *value, long n)
74*4882a593Smuzhiyun {
75*4882a593Smuzhiyun 	(void)__atomic_add_fetch(value, n, __ATOMIC_RELAXED);
76*4882a593Smuzhiyun }
77*4882a593Smuzhiyun 
atomic_swap(long * value,long n)78*4882a593Smuzhiyun static inline long atomic_swap(long *value, long n)
79*4882a593Smuzhiyun {
80*4882a593Smuzhiyun 	return __atomic_exchange_n(value, n, __ATOMIC_RELAXED);
81*4882a593Smuzhiyun }
82