1 #include <stdio.h> 2 #include <unistd.h> 3 #include <stdlib.h> 4 #include <stdbool.h> 5 #include <string.h> 6 #include <fcntl.h> 7 #include <poll.h> 8 #include <sys/ioctl.h> 9 #include <linux/perf_event.h> 10 #include <linux/bpf.h> 11 #include "libbpf.h" 12 #include "bpf_load.h" 13 14 #define SAMPLE_PERIOD 0x7fffffffffffffffULL 15 16 static void test_bpf_perf_event(void) 17 { 18 int nr_cpus = sysconf(_SC_NPROCESSORS_CONF); 19 int *pmu_fd = malloc(nr_cpus * sizeof(int)); 20 int status, i; 21 22 struct perf_event_attr attr_insn_pmu = { 23 .freq = 0, 24 .sample_period = SAMPLE_PERIOD, 25 .inherit = 0, 26 .type = PERF_TYPE_HARDWARE, 27 .read_format = 0, 28 .sample_type = 0, 29 .config = 0,/* PMU: cycles */ 30 }; 31 32 for (i = 0; i < nr_cpus; i++) { 33 pmu_fd[i] = perf_event_open(&attr_insn_pmu, -1/*pid*/, i/*cpu*/, -1/*group_fd*/, 0); 34 if (pmu_fd[i] < 0) { 35 printf("event syscall failed\n"); 36 goto exit; 37 } 38 39 bpf_update_elem(map_fd[0], &i, &pmu_fd[i], BPF_ANY); 40 ioctl(pmu_fd[i], PERF_EVENT_IOC_ENABLE, 0); 41 } 42 43 status = system("ls > /dev/null"); 44 if (status) 45 goto exit; 46 status = system("sleep 2"); 47 if (status) 48 goto exit; 49 50 exit: 51 for (i = 0; i < nr_cpus; i++) 52 close(pmu_fd[i]); 53 close(map_fd[0]); 54 free(pmu_fd); 55 } 56 57 int main(int argc, char **argv) 58 { 59 char filename[256]; 60 61 snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); 62 63 if (load_bpf_file(filename)) { 64 printf("%s", bpf_log_buf); 65 return 1; 66 } 67 68 test_bpf_perf_event(); 69 read_trace_pipe(); 70 71 return 0; 72 } 73