0001
0002
0003 #include <test_progs.h>
0004 #include "get_branch_snapshot.skel.h"
0005
0006 static int *pfd_array;
0007 static int cpu_cnt;
0008
0009 static bool is_hypervisor(void)
0010 {
0011 char *line = NULL;
0012 bool ret = false;
0013 size_t len;
0014 FILE *fp;
0015
0016 fp = fopen("/proc/cpuinfo", "r");
0017 if (!fp)
0018 return false;
0019
0020 while (getline(&line, &len, fp) != -1) {
0021 if (!strncmp(line, "flags", 5)) {
0022 if (strstr(line, "hypervisor") != NULL)
0023 ret = true;
0024 break;
0025 }
0026 }
0027
0028 free(line);
0029 fclose(fp);
0030 return ret;
0031 }
0032
0033 static int create_perf_events(void)
0034 {
0035 struct perf_event_attr attr = {0};
0036 int cpu;
0037
0038
0039 attr.size = sizeof(attr);
0040 attr.type = PERF_TYPE_RAW;
0041 attr.config = 0x1b00;
0042 attr.sample_type = PERF_SAMPLE_BRANCH_STACK;
0043 attr.branch_sample_type = PERF_SAMPLE_BRANCH_KERNEL |
0044 PERF_SAMPLE_BRANCH_USER | PERF_SAMPLE_BRANCH_ANY;
0045
0046 cpu_cnt = libbpf_num_possible_cpus();
0047 pfd_array = malloc(sizeof(int) * cpu_cnt);
0048 if (!pfd_array) {
0049 cpu_cnt = 0;
0050 return 1;
0051 }
0052
0053 for (cpu = 0; cpu < cpu_cnt; cpu++) {
0054 pfd_array[cpu] = syscall(__NR_perf_event_open, &attr,
0055 -1, cpu, -1, PERF_FLAG_FD_CLOEXEC);
0056 if (pfd_array[cpu] < 0)
0057 break;
0058 }
0059
0060 return cpu == 0;
0061 }
0062
0063 static void close_perf_events(void)
0064 {
0065 int cpu, fd;
0066
0067 for (cpu = 0; cpu < cpu_cnt; cpu++) {
0068 fd = pfd_array[cpu];
0069 if (fd < 0)
0070 break;
0071 close(fd);
0072 }
0073 free(pfd_array);
0074 }
0075
0076 void serial_test_get_branch_snapshot(void)
0077 {
0078 struct get_branch_snapshot *skel = NULL;
0079 int err;
0080
0081
0082 if (is_hypervisor()) {
0083 test__skip();
0084 return;
0085 }
0086
0087 if (create_perf_events()) {
0088 test__skip();
0089 goto cleanup;
0090 }
0091
0092 skel = get_branch_snapshot__open_and_load();
0093 if (!ASSERT_OK_PTR(skel, "get_branch_snapshot__open_and_load"))
0094 goto cleanup;
0095
0096 err = kallsyms_find("bpf_testmod_loop_test", &skel->bss->address_low);
0097 if (!ASSERT_OK(err, "kallsyms_find"))
0098 goto cleanup;
0099
0100
0101
0102
0103 skel->bss->address_high = skel->bss->address_low + 128;
0104
0105 err = get_branch_snapshot__attach(skel);
0106 if (!ASSERT_OK(err, "get_branch_snapshot__attach"))
0107 goto cleanup;
0108
0109 trigger_module_test_read(100);
0110
0111 if (skel->bss->total_entries < 16) {
0112
0113 test__skip();
0114 goto cleanup;
0115 }
0116
0117 ASSERT_GT(skel->bss->test1_hits, 6, "find_looptest_in_lbr");
0118
0119
0120
0121
0122
0123
0124
0125 ASSERT_LT(skel->bss->wasted_entries, 10, "check_wasted_entries");
0126
0127 cleanup:
0128 get_branch_snapshot__destroy(skel);
0129 close_perf_events();
0130 }