18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* Copyright (c) 2016 Facebook 38c2ecf20Sopenharmony_ci */ 48c2ecf20Sopenharmony_ci#include <stdio.h> 58c2ecf20Sopenharmony_ci#include <unistd.h> 68c2ecf20Sopenharmony_ci#include <stdlib.h> 78c2ecf20Sopenharmony_ci#include <stdbool.h> 88c2ecf20Sopenharmony_ci#include <string.h> 98c2ecf20Sopenharmony_ci#include <linux/perf_event.h> 108c2ecf20Sopenharmony_ci#include <linux/bpf.h> 118c2ecf20Sopenharmony_ci#include <signal.h> 128c2ecf20Sopenharmony_ci#include <errno.h> 138c2ecf20Sopenharmony_ci#include <sys/resource.h> 148c2ecf20Sopenharmony_ci#include <bpf/bpf.h> 158c2ecf20Sopenharmony_ci#include <bpf/libbpf.h> 168c2ecf20Sopenharmony_ci#include "perf-sys.h" 178c2ecf20Sopenharmony_ci#include "trace_helpers.h" 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#define SAMPLE_FREQ 50 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_cistatic int pid; 228c2ecf20Sopenharmony_ci/* counts, stackmap */ 238c2ecf20Sopenharmony_cistatic int map_fd[2]; 248c2ecf20Sopenharmony_cistruct bpf_program *prog; 258c2ecf20Sopenharmony_cistatic bool sys_read_seen, sys_write_seen; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_cistatic void print_ksym(__u64 addr) 288c2ecf20Sopenharmony_ci{ 298c2ecf20Sopenharmony_ci struct ksym *sym; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci if (!addr) 328c2ecf20Sopenharmony_ci return; 338c2ecf20Sopenharmony_ci sym = ksym_search(addr); 348c2ecf20Sopenharmony_ci if (!sym) { 358c2ecf20Sopenharmony_ci printf("ksym not found. Is kallsyms loaded?\n"); 368c2ecf20Sopenharmony_ci return; 378c2ecf20Sopenharmony_ci } 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci printf("%s;", sym->name); 408c2ecf20Sopenharmony_ci if (!strstr(sym->name, "sys_read")) 418c2ecf20Sopenharmony_ci sys_read_seen = true; 428c2ecf20Sopenharmony_ci else if (!strstr(sym->name, "sys_write")) 438c2ecf20Sopenharmony_ci sys_write_seen = true; 448c2ecf20Sopenharmony_ci} 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_cistatic void print_addr(__u64 addr) 478c2ecf20Sopenharmony_ci{ 488c2ecf20Sopenharmony_ci if (!addr) 498c2ecf20Sopenharmony_ci return; 508c2ecf20Sopenharmony_ci printf("%llx;", addr); 518c2ecf20Sopenharmony_ci} 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci#define TASK_COMM_LEN 16 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_cistruct key_t { 568c2ecf20Sopenharmony_ci char comm[TASK_COMM_LEN]; 578c2ecf20Sopenharmony_ci __u32 kernstack; 588c2ecf20Sopenharmony_ci __u32 userstack; 598c2ecf20Sopenharmony_ci}; 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_cistatic void print_stack(struct key_t *key, __u64 count) 628c2ecf20Sopenharmony_ci{ 638c2ecf20Sopenharmony_ci __u64 ip[PERF_MAX_STACK_DEPTH] = {}; 648c2ecf20Sopenharmony_ci static bool warned; 658c2ecf20Sopenharmony_ci int i; 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci printf("%3lld %s;", count, key->comm); 688c2ecf20Sopenharmony_ci if (bpf_map_lookup_elem(map_fd[1], &key->kernstack, ip) != 0) { 698c2ecf20Sopenharmony_ci printf("---;"); 708c2ecf20Sopenharmony_ci } else { 718c2ecf20Sopenharmony_ci for (i = PERF_MAX_STACK_DEPTH - 1; i >= 0; i--) 728c2ecf20Sopenharmony_ci print_ksym(ip[i]); 738c2ecf20Sopenharmony_ci } 748c2ecf20Sopenharmony_ci printf("-;"); 758c2ecf20Sopenharmony_ci if (bpf_map_lookup_elem(map_fd[1], &key->userstack, ip) != 0) { 768c2ecf20Sopenharmony_ci printf("---;"); 778c2ecf20Sopenharmony_ci } else { 788c2ecf20Sopenharmony_ci for (i = PERF_MAX_STACK_DEPTH - 1; i >= 0; i--) 798c2ecf20Sopenharmony_ci print_addr(ip[i]); 808c2ecf20Sopenharmony_ci } 818c2ecf20Sopenharmony_ci if (count < 6) 828c2ecf20Sopenharmony_ci printf("\r"); 838c2ecf20Sopenharmony_ci else 848c2ecf20Sopenharmony_ci printf("\n"); 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci if (key->kernstack == -EEXIST && !warned) { 878c2ecf20Sopenharmony_ci printf("stackmap collisions seen. Consider increasing size\n"); 888c2ecf20Sopenharmony_ci warned = true; 898c2ecf20Sopenharmony_ci } else if ((int)key->kernstack < 0 && (int)key->userstack < 0) { 908c2ecf20Sopenharmony_ci printf("err stackid %d %d\n", key->kernstack, key->userstack); 918c2ecf20Sopenharmony_ci } 928c2ecf20Sopenharmony_ci} 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_cistatic void err_exit(int err) 958c2ecf20Sopenharmony_ci{ 968c2ecf20Sopenharmony_ci kill(pid, SIGKILL); 978c2ecf20Sopenharmony_ci exit(err); 988c2ecf20Sopenharmony_ci} 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_cistatic void print_stacks(void) 1018c2ecf20Sopenharmony_ci{ 1028c2ecf20Sopenharmony_ci struct key_t key = {}, next_key; 1038c2ecf20Sopenharmony_ci __u64 value; 1048c2ecf20Sopenharmony_ci __u32 stackid = 0, next_id; 1058c2ecf20Sopenharmony_ci int error = 1, fd = map_fd[0], stack_map = map_fd[1]; 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci sys_read_seen = sys_write_seen = false; 1088c2ecf20Sopenharmony_ci while (bpf_map_get_next_key(fd, &key, &next_key) == 0) { 1098c2ecf20Sopenharmony_ci bpf_map_lookup_elem(fd, &next_key, &value); 1108c2ecf20Sopenharmony_ci print_stack(&next_key, value); 1118c2ecf20Sopenharmony_ci bpf_map_delete_elem(fd, &next_key); 1128c2ecf20Sopenharmony_ci key = next_key; 1138c2ecf20Sopenharmony_ci } 1148c2ecf20Sopenharmony_ci printf("\n"); 1158c2ecf20Sopenharmony_ci if (!sys_read_seen || !sys_write_seen) { 1168c2ecf20Sopenharmony_ci printf("BUG kernel stack doesn't contain sys_read() and sys_write()\n"); 1178c2ecf20Sopenharmony_ci err_exit(error); 1188c2ecf20Sopenharmony_ci } 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci /* clear stack map */ 1218c2ecf20Sopenharmony_ci while (bpf_map_get_next_key(stack_map, &stackid, &next_id) == 0) { 1228c2ecf20Sopenharmony_ci bpf_map_delete_elem(stack_map, &next_id); 1238c2ecf20Sopenharmony_ci stackid = next_id; 1248c2ecf20Sopenharmony_ci } 1258c2ecf20Sopenharmony_ci} 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_cistatic inline int generate_load(void) 1288c2ecf20Sopenharmony_ci{ 1298c2ecf20Sopenharmony_ci if (system("dd if=/dev/zero of=/dev/null count=5000k status=none") < 0) { 1308c2ecf20Sopenharmony_ci printf("failed to generate some load with dd: %s\n", strerror(errno)); 1318c2ecf20Sopenharmony_ci return -1; 1328c2ecf20Sopenharmony_ci } 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci return 0; 1358c2ecf20Sopenharmony_ci} 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_cistatic void test_perf_event_all_cpu(struct perf_event_attr *attr) 1388c2ecf20Sopenharmony_ci{ 1398c2ecf20Sopenharmony_ci int nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); 1408c2ecf20Sopenharmony_ci struct bpf_link **links = calloc(nr_cpus, sizeof(struct bpf_link *)); 1418c2ecf20Sopenharmony_ci int i, pmu_fd, error = 1; 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci if (!links) { 1448c2ecf20Sopenharmony_ci printf("malloc of links failed\n"); 1458c2ecf20Sopenharmony_ci goto err; 1468c2ecf20Sopenharmony_ci } 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci /* system wide perf event, no need to inherit */ 1498c2ecf20Sopenharmony_ci attr->inherit = 0; 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci /* open perf_event on all cpus */ 1528c2ecf20Sopenharmony_ci for (i = 0; i < nr_cpus; i++) { 1538c2ecf20Sopenharmony_ci pmu_fd = sys_perf_event_open(attr, -1, i, -1, 0); 1548c2ecf20Sopenharmony_ci if (pmu_fd < 0) { 1558c2ecf20Sopenharmony_ci printf("sys_perf_event_open failed\n"); 1568c2ecf20Sopenharmony_ci goto all_cpu_err; 1578c2ecf20Sopenharmony_ci } 1588c2ecf20Sopenharmony_ci links[i] = bpf_program__attach_perf_event(prog, pmu_fd); 1598c2ecf20Sopenharmony_ci if (libbpf_get_error(links[i])) { 1608c2ecf20Sopenharmony_ci printf("bpf_program__attach_perf_event failed\n"); 1618c2ecf20Sopenharmony_ci links[i] = NULL; 1628c2ecf20Sopenharmony_ci close(pmu_fd); 1638c2ecf20Sopenharmony_ci goto all_cpu_err; 1648c2ecf20Sopenharmony_ci } 1658c2ecf20Sopenharmony_ci } 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci if (generate_load() < 0) 1688c2ecf20Sopenharmony_ci goto all_cpu_err; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci print_stacks(); 1718c2ecf20Sopenharmony_ci error = 0; 1728c2ecf20Sopenharmony_ciall_cpu_err: 1738c2ecf20Sopenharmony_ci for (i--; i >= 0; i--) 1748c2ecf20Sopenharmony_ci bpf_link__destroy(links[i]); 1758c2ecf20Sopenharmony_cierr: 1768c2ecf20Sopenharmony_ci free(links); 1778c2ecf20Sopenharmony_ci if (error) 1788c2ecf20Sopenharmony_ci err_exit(error); 1798c2ecf20Sopenharmony_ci} 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_cistatic void test_perf_event_task(struct perf_event_attr *attr) 1828c2ecf20Sopenharmony_ci{ 1838c2ecf20Sopenharmony_ci struct bpf_link *link = NULL; 1848c2ecf20Sopenharmony_ci int pmu_fd, error = 1; 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_ci /* per task perf event, enable inherit so the "dd ..." command can be traced properly. 1878c2ecf20Sopenharmony_ci * Enabling inherit will cause bpf_perf_prog_read_time helper failure. 1888c2ecf20Sopenharmony_ci */ 1898c2ecf20Sopenharmony_ci attr->inherit = 1; 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci /* open task bound event */ 1928c2ecf20Sopenharmony_ci pmu_fd = sys_perf_event_open(attr, 0, -1, -1, 0); 1938c2ecf20Sopenharmony_ci if (pmu_fd < 0) { 1948c2ecf20Sopenharmony_ci printf("sys_perf_event_open failed\n"); 1958c2ecf20Sopenharmony_ci goto err; 1968c2ecf20Sopenharmony_ci } 1978c2ecf20Sopenharmony_ci link = bpf_program__attach_perf_event(prog, pmu_fd); 1988c2ecf20Sopenharmony_ci if (libbpf_get_error(link)) { 1998c2ecf20Sopenharmony_ci printf("bpf_program__attach_perf_event failed\n"); 2008c2ecf20Sopenharmony_ci link = NULL; 2018c2ecf20Sopenharmony_ci close(pmu_fd); 2028c2ecf20Sopenharmony_ci goto err; 2038c2ecf20Sopenharmony_ci } 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci if (generate_load() < 0) 2068c2ecf20Sopenharmony_ci goto err; 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ci print_stacks(); 2098c2ecf20Sopenharmony_ci error = 0; 2108c2ecf20Sopenharmony_cierr: 2118c2ecf20Sopenharmony_ci bpf_link__destroy(link); 2128c2ecf20Sopenharmony_ci if (error) 2138c2ecf20Sopenharmony_ci err_exit(error); 2148c2ecf20Sopenharmony_ci} 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_cistatic void test_bpf_perf_event(void) 2178c2ecf20Sopenharmony_ci{ 2188c2ecf20Sopenharmony_ci struct perf_event_attr attr_type_hw = { 2198c2ecf20Sopenharmony_ci .sample_freq = SAMPLE_FREQ, 2208c2ecf20Sopenharmony_ci .freq = 1, 2218c2ecf20Sopenharmony_ci .type = PERF_TYPE_HARDWARE, 2228c2ecf20Sopenharmony_ci .config = PERF_COUNT_HW_CPU_CYCLES, 2238c2ecf20Sopenharmony_ci }; 2248c2ecf20Sopenharmony_ci struct perf_event_attr attr_type_sw = { 2258c2ecf20Sopenharmony_ci .sample_freq = SAMPLE_FREQ, 2268c2ecf20Sopenharmony_ci .freq = 1, 2278c2ecf20Sopenharmony_ci .type = PERF_TYPE_SOFTWARE, 2288c2ecf20Sopenharmony_ci .config = PERF_COUNT_SW_CPU_CLOCK, 2298c2ecf20Sopenharmony_ci }; 2308c2ecf20Sopenharmony_ci struct perf_event_attr attr_hw_cache_l1d = { 2318c2ecf20Sopenharmony_ci .sample_freq = SAMPLE_FREQ, 2328c2ecf20Sopenharmony_ci .freq = 1, 2338c2ecf20Sopenharmony_ci .type = PERF_TYPE_HW_CACHE, 2348c2ecf20Sopenharmony_ci .config = 2358c2ecf20Sopenharmony_ci PERF_COUNT_HW_CACHE_L1D | 2368c2ecf20Sopenharmony_ci (PERF_COUNT_HW_CACHE_OP_READ << 8) | 2378c2ecf20Sopenharmony_ci (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16), 2388c2ecf20Sopenharmony_ci }; 2398c2ecf20Sopenharmony_ci struct perf_event_attr attr_hw_cache_branch_miss = { 2408c2ecf20Sopenharmony_ci .sample_freq = SAMPLE_FREQ, 2418c2ecf20Sopenharmony_ci .freq = 1, 2428c2ecf20Sopenharmony_ci .type = PERF_TYPE_HW_CACHE, 2438c2ecf20Sopenharmony_ci .config = 2448c2ecf20Sopenharmony_ci PERF_COUNT_HW_CACHE_BPU | 2458c2ecf20Sopenharmony_ci (PERF_COUNT_HW_CACHE_OP_READ << 8) | 2468c2ecf20Sopenharmony_ci (PERF_COUNT_HW_CACHE_RESULT_MISS << 16), 2478c2ecf20Sopenharmony_ci }; 2488c2ecf20Sopenharmony_ci struct perf_event_attr attr_type_raw = { 2498c2ecf20Sopenharmony_ci .sample_freq = SAMPLE_FREQ, 2508c2ecf20Sopenharmony_ci .freq = 1, 2518c2ecf20Sopenharmony_ci .type = PERF_TYPE_RAW, 2528c2ecf20Sopenharmony_ci /* Intel Instruction Retired */ 2538c2ecf20Sopenharmony_ci .config = 0xc0, 2548c2ecf20Sopenharmony_ci }; 2558c2ecf20Sopenharmony_ci struct perf_event_attr attr_type_raw_lock_load = { 2568c2ecf20Sopenharmony_ci .sample_freq = SAMPLE_FREQ, 2578c2ecf20Sopenharmony_ci .freq = 1, 2588c2ecf20Sopenharmony_ci .type = PERF_TYPE_RAW, 2598c2ecf20Sopenharmony_ci /* Intel MEM_UOPS_RETIRED.LOCK_LOADS */ 2608c2ecf20Sopenharmony_ci .config = 0x21d0, 2618c2ecf20Sopenharmony_ci /* Request to record lock address from PEBS */ 2628c2ecf20Sopenharmony_ci .sample_type = PERF_SAMPLE_ADDR, 2638c2ecf20Sopenharmony_ci /* Record address value requires precise event */ 2648c2ecf20Sopenharmony_ci .precise_ip = 2, 2658c2ecf20Sopenharmony_ci }; 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci printf("Test HW_CPU_CYCLES\n"); 2688c2ecf20Sopenharmony_ci test_perf_event_all_cpu(&attr_type_hw); 2698c2ecf20Sopenharmony_ci test_perf_event_task(&attr_type_hw); 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci printf("Test SW_CPU_CLOCK\n"); 2728c2ecf20Sopenharmony_ci test_perf_event_all_cpu(&attr_type_sw); 2738c2ecf20Sopenharmony_ci test_perf_event_task(&attr_type_sw); 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_ci printf("Test HW_CACHE_L1D\n"); 2768c2ecf20Sopenharmony_ci test_perf_event_all_cpu(&attr_hw_cache_l1d); 2778c2ecf20Sopenharmony_ci test_perf_event_task(&attr_hw_cache_l1d); 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci printf("Test HW_CACHE_BPU\n"); 2808c2ecf20Sopenharmony_ci test_perf_event_all_cpu(&attr_hw_cache_branch_miss); 2818c2ecf20Sopenharmony_ci test_perf_event_task(&attr_hw_cache_branch_miss); 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci printf("Test Instruction Retired\n"); 2848c2ecf20Sopenharmony_ci test_perf_event_all_cpu(&attr_type_raw); 2858c2ecf20Sopenharmony_ci test_perf_event_task(&attr_type_raw); 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci printf("Test Lock Load\n"); 2888c2ecf20Sopenharmony_ci test_perf_event_all_cpu(&attr_type_raw_lock_load); 2898c2ecf20Sopenharmony_ci test_perf_event_task(&attr_type_raw_lock_load); 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_ci printf("*** PASS ***\n"); 2928c2ecf20Sopenharmony_ci} 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_ciint main(int argc, char **argv) 2968c2ecf20Sopenharmony_ci{ 2978c2ecf20Sopenharmony_ci struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY}; 2988c2ecf20Sopenharmony_ci struct bpf_object *obj = NULL; 2998c2ecf20Sopenharmony_ci char filename[256]; 3008c2ecf20Sopenharmony_ci int error = 1; 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_ci snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); 3038c2ecf20Sopenharmony_ci setrlimit(RLIMIT_MEMLOCK, &r); 3048c2ecf20Sopenharmony_ci 3058c2ecf20Sopenharmony_ci signal(SIGINT, err_exit); 3068c2ecf20Sopenharmony_ci signal(SIGTERM, err_exit); 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci if (load_kallsyms()) { 3098c2ecf20Sopenharmony_ci printf("failed to process /proc/kallsyms\n"); 3108c2ecf20Sopenharmony_ci goto cleanup; 3118c2ecf20Sopenharmony_ci } 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_ci obj = bpf_object__open_file(filename, NULL); 3148c2ecf20Sopenharmony_ci if (libbpf_get_error(obj)) { 3158c2ecf20Sopenharmony_ci printf("opening BPF object file failed\n"); 3168c2ecf20Sopenharmony_ci obj = NULL; 3178c2ecf20Sopenharmony_ci goto cleanup; 3188c2ecf20Sopenharmony_ci } 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci prog = bpf_object__find_program_by_name(obj, "bpf_prog1"); 3218c2ecf20Sopenharmony_ci if (!prog) { 3228c2ecf20Sopenharmony_ci printf("finding a prog in obj file failed\n"); 3238c2ecf20Sopenharmony_ci goto cleanup; 3248c2ecf20Sopenharmony_ci } 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_ci /* load BPF program */ 3278c2ecf20Sopenharmony_ci if (bpf_object__load(obj)) { 3288c2ecf20Sopenharmony_ci printf("loading BPF object file failed\n"); 3298c2ecf20Sopenharmony_ci goto cleanup; 3308c2ecf20Sopenharmony_ci } 3318c2ecf20Sopenharmony_ci 3328c2ecf20Sopenharmony_ci map_fd[0] = bpf_object__find_map_fd_by_name(obj, "counts"); 3338c2ecf20Sopenharmony_ci map_fd[1] = bpf_object__find_map_fd_by_name(obj, "stackmap"); 3348c2ecf20Sopenharmony_ci if (map_fd[0] < 0 || map_fd[1] < 0) { 3358c2ecf20Sopenharmony_ci printf("finding a counts/stackmap map in obj file failed\n"); 3368c2ecf20Sopenharmony_ci goto cleanup; 3378c2ecf20Sopenharmony_ci } 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci pid = fork(); 3408c2ecf20Sopenharmony_ci if (pid == 0) { 3418c2ecf20Sopenharmony_ci read_trace_pipe(); 3428c2ecf20Sopenharmony_ci return 0; 3438c2ecf20Sopenharmony_ci } else if (pid == -1) { 3448c2ecf20Sopenharmony_ci printf("couldn't spawn process\n"); 3458c2ecf20Sopenharmony_ci goto cleanup; 3468c2ecf20Sopenharmony_ci } 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_ci test_bpf_perf_event(); 3498c2ecf20Sopenharmony_ci error = 0; 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_cicleanup: 3528c2ecf20Sopenharmony_ci bpf_object__close(obj); 3538c2ecf20Sopenharmony_ci err_exit(error); 3548c2ecf20Sopenharmony_ci} 355