125763b3cSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 239111695SAlexei Starovoitov #include <stdio.h> 339111695SAlexei Starovoitov #include <fcntl.h> 439111695SAlexei Starovoitov #include <poll.h> 539111695SAlexei Starovoitov #include <time.h> 639111695SAlexei Starovoitov #include <signal.h> 77cf245a3SToke Høiland-Jørgensen #include <bpf/libbpf.h> 839111695SAlexei Starovoitov 939111695SAlexei Starovoitov static __u64 time_get_ns(void) 1039111695SAlexei Starovoitov { 1139111695SAlexei Starovoitov struct timespec ts; 1239111695SAlexei Starovoitov 1339111695SAlexei Starovoitov clock_gettime(CLOCK_MONOTONIC, &ts); 1439111695SAlexei Starovoitov return ts.tv_sec * 1000000000ull + ts.tv_nsec; 1539111695SAlexei Starovoitov } 1639111695SAlexei Starovoitov 1739111695SAlexei Starovoitov static __u64 start_time; 18c17bec54SAndrii Nakryiko static __u64 cnt; 1939111695SAlexei Starovoitov 2039111695SAlexei Starovoitov #define MAX_CNT 100000ll 2139111695SAlexei Starovoitov 22c17bec54SAndrii Nakryiko static void print_bpf_output(void *ctx, int cpu, void *data, __u32 size) 2339111695SAlexei Starovoitov { 2439111695SAlexei Starovoitov struct { 2539111695SAlexei Starovoitov __u64 pid; 2639111695SAlexei Starovoitov __u64 cookie; 2739111695SAlexei Starovoitov } *e = data; 2839111695SAlexei Starovoitov 2939111695SAlexei Starovoitov if (e->cookie != 0x12345678) { 3039111695SAlexei Starovoitov printf("BUG pid %llx cookie %llx sized %d\n", 3139111695SAlexei Starovoitov e->pid, e->cookie, size); 32c17bec54SAndrii Nakryiko return; 3339111695SAlexei Starovoitov } 3439111695SAlexei Starovoitov 3539111695SAlexei Starovoitov cnt++; 3639111695SAlexei Starovoitov 3739111695SAlexei Starovoitov if (cnt == MAX_CNT) { 3839111695SAlexei Starovoitov printf("recv %lld events per sec\n", 3939111695SAlexei Starovoitov MAX_CNT * 1000000000ll / (time_get_ns() - start_time)); 40c17bec54SAndrii Nakryiko return; 4139111695SAlexei Starovoitov } 4239111695SAlexei Starovoitov } 4339111695SAlexei Starovoitov 4439111695SAlexei Starovoitov int main(int argc, char **argv) 4539111695SAlexei Starovoitov { 463677d0a1SDaniel T. Lee struct bpf_link *link = NULL; 473677d0a1SDaniel T. Lee struct bpf_program *prog; 48c17bec54SAndrii Nakryiko struct perf_buffer *pb; 493677d0a1SDaniel T. Lee struct bpf_object *obj; 503677d0a1SDaniel T. Lee int map_fd, ret = 0; 5139111695SAlexei Starovoitov char filename[256]; 5239111695SAlexei Starovoitov FILE *f; 5339111695SAlexei Starovoitov 5439111695SAlexei Starovoitov snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); 553677d0a1SDaniel T. Lee obj = bpf_object__open_file(filename, NULL); 563677d0a1SDaniel T. Lee if (libbpf_get_error(obj)) { 573677d0a1SDaniel T. Lee fprintf(stderr, "ERROR: opening BPF object file failed\n"); 583677d0a1SDaniel T. Lee return 0; 593677d0a1SDaniel T. Lee } 6039111695SAlexei Starovoitov 613677d0a1SDaniel T. Lee /* load BPF program */ 623677d0a1SDaniel T. Lee if (bpf_object__load(obj)) { 633677d0a1SDaniel T. Lee fprintf(stderr, "ERROR: loading BPF object file failed\n"); 643677d0a1SDaniel T. Lee goto cleanup; 653677d0a1SDaniel T. Lee } 663677d0a1SDaniel T. Lee 673677d0a1SDaniel T. Lee map_fd = bpf_object__find_map_fd_by_name(obj, "my_map"); 683677d0a1SDaniel T. Lee if (map_fd < 0) { 693677d0a1SDaniel T. Lee fprintf(stderr, "ERROR: finding a map in obj file failed\n"); 703677d0a1SDaniel T. Lee goto cleanup; 713677d0a1SDaniel T. Lee } 723677d0a1SDaniel T. Lee 733677d0a1SDaniel T. Lee prog = bpf_object__find_program_by_name(obj, "bpf_prog1"); 743677d0a1SDaniel T. Lee if (libbpf_get_error(prog)) { 753677d0a1SDaniel T. Lee fprintf(stderr, "ERROR: finding a prog in obj file failed\n"); 763677d0a1SDaniel T. Lee goto cleanup; 773677d0a1SDaniel T. Lee } 783677d0a1SDaniel T. Lee 793677d0a1SDaniel T. Lee link = bpf_program__attach(prog); 803677d0a1SDaniel T. Lee if (libbpf_get_error(link)) { 813677d0a1SDaniel T. Lee fprintf(stderr, "ERROR: bpf_program__attach failed\n"); 823677d0a1SDaniel T. Lee link = NULL; 833677d0a1SDaniel T. Lee goto cleanup; 8439111695SAlexei Starovoitov } 8539111695SAlexei Starovoitov 86*c58f9815SAndrii Nakryiko pb = perf_buffer__new(map_fd, 8, print_bpf_output, NULL, NULL, NULL); 87c17bec54SAndrii Nakryiko ret = libbpf_get_error(pb); 88c17bec54SAndrii Nakryiko if (ret) { 89c17bec54SAndrii Nakryiko printf("failed to setup perf_buffer: %d\n", ret); 9039111695SAlexei Starovoitov return 1; 91c17bec54SAndrii Nakryiko } 9239111695SAlexei Starovoitov 9339111695SAlexei Starovoitov f = popen("taskset 1 dd if=/dev/zero of=/dev/null", "r"); 9439111695SAlexei Starovoitov (void) f; 9539111695SAlexei Starovoitov 9639111695SAlexei Starovoitov start_time = time_get_ns(); 97c17bec54SAndrii Nakryiko while ((ret = perf_buffer__poll(pb, 1000)) >= 0 && cnt < MAX_CNT) { 98c17bec54SAndrii Nakryiko } 9928dbf861SYonghong Song kill(0, SIGINT); 1003677d0a1SDaniel T. Lee 1013677d0a1SDaniel T. Lee cleanup: 1023677d0a1SDaniel T. Lee bpf_link__destroy(link); 1033677d0a1SDaniel T. Lee bpf_object__close(obj); 10428dbf861SYonghong Song return ret; 10539111695SAlexei Starovoitov } 106