Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright (c) 2021 Facebook */
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     /* create perf event */
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     /* Skip the test before we fix LBR snapshot for hypervisor. */
0082     if (is_hypervisor()) {
0083         test__skip();
0084         return;
0085     }
0086 
0087     if (create_perf_events()) {
0088         test__skip();  /* system doesn't support LBR */
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     /* Just a guess for the end of this function, as module functions
0101      * in /proc/kallsyms could come in any order.
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         /* too few entries for the hit/waste test */
0113         test__skip();
0114         goto cleanup;
0115     }
0116 
0117     ASSERT_GT(skel->bss->test1_hits, 6, "find_looptest_in_lbr");
0118 
0119     /* Given we stop LBR in software, we will waste a few entries.
0120      * But we should try to waste as few as possible entries. We are at
0121      * about 7 on x86_64 systems.
0122      * Add a check for < 10 so that we get heads-up when something
0123      * changes and wastes too many entries.
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 }