1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2021 Facebook */ 3 #include <test_progs.h> 4 #include "get_branch_snapshot.skel.h" 5 6 static int *pfd_array; 7 static int cpu_cnt; 8 9 static int create_perf_events(void) 10 { 11 struct perf_event_attr attr = {0}; 12 int cpu; 13 14 /* create perf event */ 15 attr.size = sizeof(attr); 16 attr.type = PERF_TYPE_RAW; 17 attr.config = 0x1b00; 18 attr.sample_type = PERF_SAMPLE_BRANCH_STACK; 19 attr.branch_sample_type = PERF_SAMPLE_BRANCH_KERNEL | 20 PERF_SAMPLE_BRANCH_USER | PERF_SAMPLE_BRANCH_ANY; 21 22 cpu_cnt = libbpf_num_possible_cpus(); 23 pfd_array = malloc(sizeof(int) * cpu_cnt); 24 if (!pfd_array) { 25 cpu_cnt = 0; 26 return 1; 27 } 28 29 for (cpu = 0; cpu < cpu_cnt; cpu++) { 30 pfd_array[cpu] = syscall(__NR_perf_event_open, &attr, 31 -1, cpu, -1, PERF_FLAG_FD_CLOEXEC); 32 if (pfd_array[cpu] < 0) 33 break; 34 } 35 36 return cpu == 0; 37 } 38 39 static void close_perf_events(void) 40 { 41 int cpu = 0; 42 int fd; 43 44 while (cpu++ < cpu_cnt) { 45 fd = pfd_array[cpu]; 46 if (fd < 0) 47 break; 48 close(fd); 49 } 50 free(pfd_array); 51 } 52 53 void test_get_branch_snapshot(void) 54 { 55 struct get_branch_snapshot *skel = NULL; 56 int err; 57 58 if (create_perf_events()) { 59 test__skip(); /* system doesn't support LBR */ 60 goto cleanup; 61 } 62 63 skel = get_branch_snapshot__open_and_load(); 64 if (!ASSERT_OK_PTR(skel, "get_branch_snapshot__open_and_load")) 65 goto cleanup; 66 67 err = kallsyms_find("bpf_testmod_loop_test", &skel->bss->address_low); 68 if (!ASSERT_OK(err, "kallsyms_find")) 69 goto cleanup; 70 71 err = kallsyms_find_next("bpf_testmod_loop_test", &skel->bss->address_high); 72 if (!ASSERT_OK(err, "kallsyms_find_next")) 73 goto cleanup; 74 75 err = get_branch_snapshot__attach(skel); 76 if (!ASSERT_OK(err, "get_branch_snapshot__attach")) 77 goto cleanup; 78 79 trigger_module_test_read(100); 80 81 if (skel->bss->total_entries < 16) { 82 /* too few entries for the hit/waste test */ 83 test__skip(); 84 goto cleanup; 85 } 86 87 ASSERT_GT(skel->bss->test1_hits, 6, "find_looptest_in_lbr"); 88 89 /* Given we stop LBR in software, we will waste a few entries. 90 * But we should try to waste as few as possible entries. We are at 91 * about 7 on x86_64 systems. 92 * Add a check for < 10 so that we get heads-up when something 93 * changes and wastes too many entries. 94 */ 95 ASSERT_LT(skel->bss->wasted_entries, 10, "check_wasted_entries"); 96 97 cleanup: 98 get_branch_snapshot__destroy(skel); 99 close_perf_events(); 100 } 101