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