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 { 46c17bec54SAndrii Nakryiko struct perf_buffer_opts pb_opts = {}; 47*3677d0a1SDaniel T. Lee struct bpf_link *link = NULL; 48*3677d0a1SDaniel T. Lee struct bpf_program *prog; 49c17bec54SAndrii Nakryiko struct perf_buffer *pb; 50*3677d0a1SDaniel T. Lee struct bpf_object *obj; 51*3677d0a1SDaniel T. Lee int map_fd, ret = 0; 5239111695SAlexei Starovoitov char filename[256]; 5339111695SAlexei Starovoitov FILE *f; 5439111695SAlexei Starovoitov 5539111695SAlexei Starovoitov snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); 56*3677d0a1SDaniel T. Lee obj = bpf_object__open_file(filename, NULL); 57*3677d0a1SDaniel T. Lee if (libbpf_get_error(obj)) { 58*3677d0a1SDaniel T. Lee fprintf(stderr, "ERROR: opening BPF object file failed\n"); 59*3677d0a1SDaniel T. Lee return 0; 60*3677d0a1SDaniel T. Lee } 6139111695SAlexei Starovoitov 62*3677d0a1SDaniel T. Lee /* load BPF program */ 63*3677d0a1SDaniel T. Lee if (bpf_object__load(obj)) { 64*3677d0a1SDaniel T. Lee fprintf(stderr, "ERROR: loading BPF object file failed\n"); 65*3677d0a1SDaniel T. Lee goto cleanup; 66*3677d0a1SDaniel T. Lee } 67*3677d0a1SDaniel T. Lee 68*3677d0a1SDaniel T. Lee map_fd = bpf_object__find_map_fd_by_name(obj, "my_map"); 69*3677d0a1SDaniel T. Lee if (map_fd < 0) { 70*3677d0a1SDaniel T. Lee fprintf(stderr, "ERROR: finding a map in obj file failed\n"); 71*3677d0a1SDaniel T. Lee goto cleanup; 72*3677d0a1SDaniel T. Lee } 73*3677d0a1SDaniel T. Lee 74*3677d0a1SDaniel T. Lee prog = bpf_object__find_program_by_name(obj, "bpf_prog1"); 75*3677d0a1SDaniel T. Lee if (libbpf_get_error(prog)) { 76*3677d0a1SDaniel T. Lee fprintf(stderr, "ERROR: finding a prog in obj file failed\n"); 77*3677d0a1SDaniel T. Lee goto cleanup; 78*3677d0a1SDaniel T. Lee } 79*3677d0a1SDaniel T. Lee 80*3677d0a1SDaniel T. Lee link = bpf_program__attach(prog); 81*3677d0a1SDaniel T. Lee if (libbpf_get_error(link)) { 82*3677d0a1SDaniel T. Lee fprintf(stderr, "ERROR: bpf_program__attach failed\n"); 83*3677d0a1SDaniel T. Lee link = NULL; 84*3677d0a1SDaniel T. Lee goto cleanup; 8539111695SAlexei Starovoitov } 8639111695SAlexei Starovoitov 87c17bec54SAndrii Nakryiko pb_opts.sample_cb = print_bpf_output; 88*3677d0a1SDaniel T. Lee pb = perf_buffer__new(map_fd, 8, &pb_opts); 89c17bec54SAndrii Nakryiko ret = libbpf_get_error(pb); 90c17bec54SAndrii Nakryiko if (ret) { 91c17bec54SAndrii Nakryiko printf("failed to setup perf_buffer: %d\n", ret); 9239111695SAlexei Starovoitov return 1; 93c17bec54SAndrii Nakryiko } 9439111695SAlexei Starovoitov 9539111695SAlexei Starovoitov f = popen("taskset 1 dd if=/dev/zero of=/dev/null", "r"); 9639111695SAlexei Starovoitov (void) f; 9739111695SAlexei Starovoitov 9839111695SAlexei Starovoitov start_time = time_get_ns(); 99c17bec54SAndrii Nakryiko while ((ret = perf_buffer__poll(pb, 1000)) >= 0 && cnt < MAX_CNT) { 100c17bec54SAndrii Nakryiko } 10128dbf861SYonghong Song kill(0, SIGINT); 102*3677d0a1SDaniel T. Lee 103*3677d0a1SDaniel T. Lee cleanup: 104*3677d0a1SDaniel T. Lee bpf_link__destroy(link); 105*3677d0a1SDaniel T. Lee bpf_object__close(obj); 10628dbf861SYonghong Song return ret; 10739111695SAlexei Starovoitov } 108