1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef __PERF_BPF_COUNTER_H 3 #define __PERF_BPF_COUNTER_H 1 4 5 #include <linux/list.h> 6 #include <sys/resource.h> 7 8 #ifdef HAVE_LIBBPF_SUPPORT 9 #include <bpf/bpf.h> 10 #include <bpf/btf.h> 11 #include <bpf/libbpf.h> 12 #endif 13 14 struct evsel; 15 struct target; 16 struct bpf_counter; 17 18 typedef int (*bpf_counter_evsel_op)(struct evsel *evsel); 19 typedef int (*bpf_counter_evsel_target_op)(struct evsel *evsel, 20 struct target *target); 21 typedef int (*bpf_counter_evsel_install_pe_op)(struct evsel *evsel, 22 int cpu_map_idx, 23 int fd); 24 25 struct bpf_counter_ops { 26 bpf_counter_evsel_target_op load; 27 bpf_counter_evsel_op enable; 28 bpf_counter_evsel_op disable; 29 bpf_counter_evsel_op read; 30 bpf_counter_evsel_op destroy; 31 bpf_counter_evsel_install_pe_op install_pe; 32 }; 33 34 struct bpf_counter { 35 void *skel; 36 struct list_head list; 37 }; 38 39 #ifdef HAVE_BPF_SKEL 40 41 int bpf_counter__load(struct evsel *evsel, struct target *target); 42 int bpf_counter__enable(struct evsel *evsel); 43 int bpf_counter__disable(struct evsel *evsel); 44 int bpf_counter__read(struct evsel *evsel); 45 void bpf_counter__destroy(struct evsel *evsel); 46 int bpf_counter__install_pe(struct evsel *evsel, int cpu_map_idx, int fd); 47 48 #else /* HAVE_BPF_SKEL */ 49 50 #include <linux/err.h> 51 52 static inline int bpf_counter__load(struct evsel *evsel __maybe_unused, 53 struct target *target __maybe_unused) 54 { 55 return 0; 56 } 57 58 static inline int bpf_counter__enable(struct evsel *evsel __maybe_unused) 59 { 60 return 0; 61 } 62 63 static inline int bpf_counter__disable(struct evsel *evsel __maybe_unused) 64 { 65 return 0; 66 } 67 68 static inline int bpf_counter__read(struct evsel *evsel __maybe_unused) 69 { 70 return -EAGAIN; 71 } 72 73 static inline void bpf_counter__destroy(struct evsel *evsel __maybe_unused) 74 { 75 } 76 77 static inline int bpf_counter__install_pe(struct evsel *evsel __maybe_unused, 78 int cpu __maybe_unused, 79 int fd __maybe_unused) 80 { 81 return 0; 82 } 83 84 #endif /* HAVE_BPF_SKEL */ 85 86 static inline void set_max_rlimit(void) 87 { 88 struct rlimit rinf = { RLIM_INFINITY, RLIM_INFINITY }; 89 90 setrlimit(RLIMIT_MEMLOCK, &rinf); 91 } 92 93 #ifdef HAVE_BPF_SKEL 94 95 static inline __u32 bpf_link_get_id(int fd) 96 { 97 struct bpf_link_info link_info = { .id = 0, }; 98 __u32 link_info_len = sizeof(link_info); 99 100 bpf_obj_get_info_by_fd(fd, &link_info, &link_info_len); 101 return link_info.id; 102 } 103 104 static inline __u32 bpf_link_get_prog_id(int fd) 105 { 106 struct bpf_link_info link_info = { .id = 0, }; 107 __u32 link_info_len = sizeof(link_info); 108 109 bpf_obj_get_info_by_fd(fd, &link_info, &link_info_len); 110 return link_info.prog_id; 111 } 112 113 static inline __u32 bpf_map_get_id(int fd) 114 { 115 struct bpf_map_info map_info = { .id = 0, }; 116 __u32 map_info_len = sizeof(map_info); 117 118 bpf_obj_get_info_by_fd(fd, &map_info, &map_info_len); 119 return map_info.id; 120 } 121 122 /* trigger the leader program on a cpu */ 123 static inline int bperf_trigger_reading(int prog_fd, int cpu) 124 { 125 DECLARE_LIBBPF_OPTS(bpf_test_run_opts, opts, 126 .ctx_in = NULL, 127 .ctx_size_in = 0, 128 .flags = BPF_F_TEST_RUN_ON_CPU, 129 .cpu = cpu, 130 .retval = 0, 131 ); 132 133 return bpf_prog_test_run_opts(prog_fd, &opts); 134 } 135 #endif /* HAVE_BPF_SKEL */ 136 137 #endif /* __PERF_BPF_COUNTER_H */ 138