162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci#include <stdio.h> 362306a36Sopenharmony_ci#include <fcntl.h> 462306a36Sopenharmony_ci#include <poll.h> 562306a36Sopenharmony_ci#include <time.h> 662306a36Sopenharmony_ci#include <signal.h> 762306a36Sopenharmony_ci#include <bpf/libbpf.h> 862306a36Sopenharmony_ci 962306a36Sopenharmony_cistatic __u64 time_get_ns(void) 1062306a36Sopenharmony_ci{ 1162306a36Sopenharmony_ci struct timespec ts; 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci clock_gettime(CLOCK_MONOTONIC, &ts); 1462306a36Sopenharmony_ci return ts.tv_sec * 1000000000ull + ts.tv_nsec; 1562306a36Sopenharmony_ci} 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_cistatic __u64 start_time; 1862306a36Sopenharmony_cistatic __u64 cnt; 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci#define MAX_CNT 100000ll 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_cistatic void print_bpf_output(void *ctx, int cpu, void *data, __u32 size) 2362306a36Sopenharmony_ci{ 2462306a36Sopenharmony_ci struct { 2562306a36Sopenharmony_ci __u64 pid; 2662306a36Sopenharmony_ci __u64 cookie; 2762306a36Sopenharmony_ci } *e = data; 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci if (e->cookie != 0x12345678) { 3062306a36Sopenharmony_ci printf("BUG pid %llx cookie %llx sized %d\n", 3162306a36Sopenharmony_ci e->pid, e->cookie, size); 3262306a36Sopenharmony_ci return; 3362306a36Sopenharmony_ci } 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci cnt++; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci if (cnt == MAX_CNT) { 3862306a36Sopenharmony_ci printf("recv %lld events per sec\n", 3962306a36Sopenharmony_ci MAX_CNT * 1000000000ll / (time_get_ns() - start_time)); 4062306a36Sopenharmony_ci return; 4162306a36Sopenharmony_ci } 4262306a36Sopenharmony_ci} 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ciint main(int argc, char **argv) 4562306a36Sopenharmony_ci{ 4662306a36Sopenharmony_ci struct bpf_link *link = NULL; 4762306a36Sopenharmony_ci struct bpf_program *prog; 4862306a36Sopenharmony_ci struct perf_buffer *pb; 4962306a36Sopenharmony_ci struct bpf_object *obj; 5062306a36Sopenharmony_ci int map_fd, ret = 0; 5162306a36Sopenharmony_ci char filename[256]; 5262306a36Sopenharmony_ci FILE *f; 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci snprintf(filename, sizeof(filename), "%s.bpf.o", argv[0]); 5562306a36Sopenharmony_ci obj = bpf_object__open_file(filename, NULL); 5662306a36Sopenharmony_ci if (libbpf_get_error(obj)) { 5762306a36Sopenharmony_ci fprintf(stderr, "ERROR: opening BPF object file failed\n"); 5862306a36Sopenharmony_ci return 0; 5962306a36Sopenharmony_ci } 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci /* load BPF program */ 6262306a36Sopenharmony_ci if (bpf_object__load(obj)) { 6362306a36Sopenharmony_ci fprintf(stderr, "ERROR: loading BPF object file failed\n"); 6462306a36Sopenharmony_ci goto cleanup; 6562306a36Sopenharmony_ci } 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci map_fd = bpf_object__find_map_fd_by_name(obj, "my_map"); 6862306a36Sopenharmony_ci if (map_fd < 0) { 6962306a36Sopenharmony_ci fprintf(stderr, "ERROR: finding a map in obj file failed\n"); 7062306a36Sopenharmony_ci goto cleanup; 7162306a36Sopenharmony_ci } 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci prog = bpf_object__find_program_by_name(obj, "bpf_prog1"); 7462306a36Sopenharmony_ci if (libbpf_get_error(prog)) { 7562306a36Sopenharmony_ci fprintf(stderr, "ERROR: finding a prog in obj file failed\n"); 7662306a36Sopenharmony_ci goto cleanup; 7762306a36Sopenharmony_ci } 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci link = bpf_program__attach(prog); 8062306a36Sopenharmony_ci if (libbpf_get_error(link)) { 8162306a36Sopenharmony_ci fprintf(stderr, "ERROR: bpf_program__attach failed\n"); 8262306a36Sopenharmony_ci link = NULL; 8362306a36Sopenharmony_ci goto cleanup; 8462306a36Sopenharmony_ci } 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci pb = perf_buffer__new(map_fd, 8, print_bpf_output, NULL, NULL, NULL); 8762306a36Sopenharmony_ci ret = libbpf_get_error(pb); 8862306a36Sopenharmony_ci if (ret) { 8962306a36Sopenharmony_ci printf("failed to setup perf_buffer: %d\n", ret); 9062306a36Sopenharmony_ci return 1; 9162306a36Sopenharmony_ci } 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci f = popen("taskset 1 dd if=/dev/zero of=/dev/null", "r"); 9462306a36Sopenharmony_ci (void) f; 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci start_time = time_get_ns(); 9762306a36Sopenharmony_ci while ((ret = perf_buffer__poll(pb, 1000)) >= 0 && cnt < MAX_CNT) { 9862306a36Sopenharmony_ci } 9962306a36Sopenharmony_ci kill(0, SIGINT); 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_cicleanup: 10262306a36Sopenharmony_ci bpf_link__destroy(link); 10362306a36Sopenharmony_ci bpf_object__close(obj); 10462306a36Sopenharmony_ci return ret; 10562306a36Sopenharmony_ci} 106