18c2ecf20Sopenharmony_ci/* Copyright (c) 2016 Facebook 28c2ecf20Sopenharmony_ci * 38c2ecf20Sopenharmony_ci * This program is free software; you can redistribute it and/or 48c2ecf20Sopenharmony_ci * modify it under the terms of version 2 of the GNU General Public 58c2ecf20Sopenharmony_ci * License as published by the Free Software Foundation. 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci#include <linux/skbuff.h> 88c2ecf20Sopenharmony_ci#include <linux/netdevice.h> 98c2ecf20Sopenharmony_ci#include <linux/version.h> 108c2ecf20Sopenharmony_ci#include <uapi/linux/bpf.h> 118c2ecf20Sopenharmony_ci#include <bpf/bpf_helpers.h> 128c2ecf20Sopenharmony_ci#include <bpf/bpf_tracing.h> 138c2ecf20Sopenharmony_ci#include <bpf/bpf_core_read.h> 148c2ecf20Sopenharmony_ci#include "trace_common.h" 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#define MAX_ENTRIES 1000 178c2ecf20Sopenharmony_ci#define MAX_NR_CPUS 1024 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_cistruct { 208c2ecf20Sopenharmony_ci __uint(type, BPF_MAP_TYPE_HASH); 218c2ecf20Sopenharmony_ci __type(key, u32); 228c2ecf20Sopenharmony_ci __type(value, long); 238c2ecf20Sopenharmony_ci __uint(max_entries, MAX_ENTRIES); 248c2ecf20Sopenharmony_ci} hash_map SEC(".maps"); 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_cistruct { 278c2ecf20Sopenharmony_ci __uint(type, BPF_MAP_TYPE_LRU_HASH); 288c2ecf20Sopenharmony_ci __type(key, u32); 298c2ecf20Sopenharmony_ci __type(value, long); 308c2ecf20Sopenharmony_ci __uint(max_entries, 10000); 318c2ecf20Sopenharmony_ci} lru_hash_map SEC(".maps"); 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_cistruct { 348c2ecf20Sopenharmony_ci __uint(type, BPF_MAP_TYPE_LRU_HASH); 358c2ecf20Sopenharmony_ci __type(key, u32); 368c2ecf20Sopenharmony_ci __type(value, long); 378c2ecf20Sopenharmony_ci __uint(max_entries, 10000); 388c2ecf20Sopenharmony_ci __uint(map_flags, BPF_F_NO_COMMON_LRU); 398c2ecf20Sopenharmony_ci} nocommon_lru_hash_map SEC(".maps"); 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_cistruct inner_lru { 428c2ecf20Sopenharmony_ci __uint(type, BPF_MAP_TYPE_LRU_HASH); 438c2ecf20Sopenharmony_ci __type(key, u32); 448c2ecf20Sopenharmony_ci __type(value, long); 458c2ecf20Sopenharmony_ci __uint(max_entries, MAX_ENTRIES); 468c2ecf20Sopenharmony_ci __uint(map_flags, BPF_F_NUMA_NODE); 478c2ecf20Sopenharmony_ci __uint(numa_node, 0); 488c2ecf20Sopenharmony_ci} inner_lru_hash_map SEC(".maps"); 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_cistruct { 518c2ecf20Sopenharmony_ci __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS); 528c2ecf20Sopenharmony_ci __uint(max_entries, MAX_NR_CPUS); 538c2ecf20Sopenharmony_ci __uint(key_size, sizeof(u32)); 548c2ecf20Sopenharmony_ci __array(values, struct inner_lru); /* use inner_lru as inner map */ 558c2ecf20Sopenharmony_ci} array_of_lru_hashs SEC(".maps") = { 568c2ecf20Sopenharmony_ci /* statically initialize the first element */ 578c2ecf20Sopenharmony_ci .values = { &inner_lru_hash_map }, 588c2ecf20Sopenharmony_ci}; 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_cistruct { 618c2ecf20Sopenharmony_ci __uint(type, BPF_MAP_TYPE_PERCPU_HASH); 628c2ecf20Sopenharmony_ci __uint(key_size, sizeof(u32)); 638c2ecf20Sopenharmony_ci __uint(value_size, sizeof(long)); 648c2ecf20Sopenharmony_ci __uint(max_entries, MAX_ENTRIES); 658c2ecf20Sopenharmony_ci} percpu_hash_map SEC(".maps"); 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_cistruct { 688c2ecf20Sopenharmony_ci __uint(type, BPF_MAP_TYPE_HASH); 698c2ecf20Sopenharmony_ci __type(key, u32); 708c2ecf20Sopenharmony_ci __type(value, long); 718c2ecf20Sopenharmony_ci __uint(max_entries, MAX_ENTRIES); 728c2ecf20Sopenharmony_ci __uint(map_flags, BPF_F_NO_PREALLOC); 738c2ecf20Sopenharmony_ci} hash_map_alloc SEC(".maps"); 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_cistruct { 768c2ecf20Sopenharmony_ci __uint(type, BPF_MAP_TYPE_PERCPU_HASH); 778c2ecf20Sopenharmony_ci __uint(key_size, sizeof(u32)); 788c2ecf20Sopenharmony_ci __uint(value_size, sizeof(long)); 798c2ecf20Sopenharmony_ci __uint(max_entries, MAX_ENTRIES); 808c2ecf20Sopenharmony_ci __uint(map_flags, BPF_F_NO_PREALLOC); 818c2ecf20Sopenharmony_ci} percpu_hash_map_alloc SEC(".maps"); 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_cistruct { 848c2ecf20Sopenharmony_ci __uint(type, BPF_MAP_TYPE_LPM_TRIE); 858c2ecf20Sopenharmony_ci __uint(key_size, 8); 868c2ecf20Sopenharmony_ci __uint(value_size, sizeof(long)); 878c2ecf20Sopenharmony_ci __uint(max_entries, 10000); 888c2ecf20Sopenharmony_ci __uint(map_flags, BPF_F_NO_PREALLOC); 898c2ecf20Sopenharmony_ci} lpm_trie_map_alloc SEC(".maps"); 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_cistruct { 928c2ecf20Sopenharmony_ci __uint(type, BPF_MAP_TYPE_ARRAY); 938c2ecf20Sopenharmony_ci __type(key, u32); 948c2ecf20Sopenharmony_ci __type(value, long); 958c2ecf20Sopenharmony_ci __uint(max_entries, MAX_ENTRIES); 968c2ecf20Sopenharmony_ci} array_map SEC(".maps"); 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_cistruct { 998c2ecf20Sopenharmony_ci __uint(type, BPF_MAP_TYPE_LRU_HASH); 1008c2ecf20Sopenharmony_ci __type(key, u32); 1018c2ecf20Sopenharmony_ci __type(value, long); 1028c2ecf20Sopenharmony_ci __uint(max_entries, MAX_ENTRIES); 1038c2ecf20Sopenharmony_ci} lru_hash_lookup_map SEC(".maps"); 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ciSEC("kprobe/" SYSCALL(sys_getuid)) 1068c2ecf20Sopenharmony_ciint stress_hmap(struct pt_regs *ctx) 1078c2ecf20Sopenharmony_ci{ 1088c2ecf20Sopenharmony_ci u32 key = bpf_get_current_pid_tgid(); 1098c2ecf20Sopenharmony_ci long init_val = 1; 1108c2ecf20Sopenharmony_ci long *value; 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci bpf_map_update_elem(&hash_map, &key, &init_val, BPF_ANY); 1138c2ecf20Sopenharmony_ci value = bpf_map_lookup_elem(&hash_map, &key); 1148c2ecf20Sopenharmony_ci if (value) 1158c2ecf20Sopenharmony_ci bpf_map_delete_elem(&hash_map, &key); 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci return 0; 1188c2ecf20Sopenharmony_ci} 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ciSEC("kprobe/" SYSCALL(sys_geteuid)) 1218c2ecf20Sopenharmony_ciint stress_percpu_hmap(struct pt_regs *ctx) 1228c2ecf20Sopenharmony_ci{ 1238c2ecf20Sopenharmony_ci u32 key = bpf_get_current_pid_tgid(); 1248c2ecf20Sopenharmony_ci long init_val = 1; 1258c2ecf20Sopenharmony_ci long *value; 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ci bpf_map_update_elem(&percpu_hash_map, &key, &init_val, BPF_ANY); 1288c2ecf20Sopenharmony_ci value = bpf_map_lookup_elem(&percpu_hash_map, &key); 1298c2ecf20Sopenharmony_ci if (value) 1308c2ecf20Sopenharmony_ci bpf_map_delete_elem(&percpu_hash_map, &key); 1318c2ecf20Sopenharmony_ci return 0; 1328c2ecf20Sopenharmony_ci} 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ciSEC("kprobe/" SYSCALL(sys_getgid)) 1358c2ecf20Sopenharmony_ciint stress_hmap_alloc(struct pt_regs *ctx) 1368c2ecf20Sopenharmony_ci{ 1378c2ecf20Sopenharmony_ci u32 key = bpf_get_current_pid_tgid(); 1388c2ecf20Sopenharmony_ci long init_val = 1; 1398c2ecf20Sopenharmony_ci long *value; 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci bpf_map_update_elem(&hash_map_alloc, &key, &init_val, BPF_ANY); 1428c2ecf20Sopenharmony_ci value = bpf_map_lookup_elem(&hash_map_alloc, &key); 1438c2ecf20Sopenharmony_ci if (value) 1448c2ecf20Sopenharmony_ci bpf_map_delete_elem(&hash_map_alloc, &key); 1458c2ecf20Sopenharmony_ci return 0; 1468c2ecf20Sopenharmony_ci} 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ciSEC("kprobe/" SYSCALL(sys_getegid)) 1498c2ecf20Sopenharmony_ciint stress_percpu_hmap_alloc(struct pt_regs *ctx) 1508c2ecf20Sopenharmony_ci{ 1518c2ecf20Sopenharmony_ci u32 key = bpf_get_current_pid_tgid(); 1528c2ecf20Sopenharmony_ci long init_val = 1; 1538c2ecf20Sopenharmony_ci long *value; 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci bpf_map_update_elem(&percpu_hash_map_alloc, &key, &init_val, BPF_ANY); 1568c2ecf20Sopenharmony_ci value = bpf_map_lookup_elem(&percpu_hash_map_alloc, &key); 1578c2ecf20Sopenharmony_ci if (value) 1588c2ecf20Sopenharmony_ci bpf_map_delete_elem(&percpu_hash_map_alloc, &key); 1598c2ecf20Sopenharmony_ci return 0; 1608c2ecf20Sopenharmony_ci} 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ciSEC("kprobe/" SYSCALL(sys_connect)) 1638c2ecf20Sopenharmony_ciint stress_lru_hmap_alloc(struct pt_regs *ctx) 1648c2ecf20Sopenharmony_ci{ 1658c2ecf20Sopenharmony_ci struct pt_regs *real_regs = (struct pt_regs *)PT_REGS_PARM1_CORE(ctx); 1668c2ecf20Sopenharmony_ci char fmt[] = "Failed at stress_lru_hmap_alloc. ret:%dn"; 1678c2ecf20Sopenharmony_ci union { 1688c2ecf20Sopenharmony_ci u16 dst6[8]; 1698c2ecf20Sopenharmony_ci struct { 1708c2ecf20Sopenharmony_ci u16 magic0; 1718c2ecf20Sopenharmony_ci u16 magic1; 1728c2ecf20Sopenharmony_ci u16 tcase; 1738c2ecf20Sopenharmony_ci u16 unused16; 1748c2ecf20Sopenharmony_ci u32 unused32; 1758c2ecf20Sopenharmony_ci u32 key; 1768c2ecf20Sopenharmony_ci }; 1778c2ecf20Sopenharmony_ci } test_params; 1788c2ecf20Sopenharmony_ci struct sockaddr_in6 *in6; 1798c2ecf20Sopenharmony_ci u16 test_case; 1808c2ecf20Sopenharmony_ci int addrlen, ret; 1818c2ecf20Sopenharmony_ci long val = 1; 1828c2ecf20Sopenharmony_ci u32 key = 0; 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci in6 = (struct sockaddr_in6 *)PT_REGS_PARM2_CORE(real_regs); 1858c2ecf20Sopenharmony_ci addrlen = (int)PT_REGS_PARM3_CORE(real_regs); 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci if (addrlen != sizeof(*in6)) 1888c2ecf20Sopenharmony_ci return 0; 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci ret = bpf_probe_read_user(test_params.dst6, sizeof(test_params.dst6), 1918c2ecf20Sopenharmony_ci &in6->sin6_addr); 1928c2ecf20Sopenharmony_ci if (ret) 1938c2ecf20Sopenharmony_ci goto done; 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ci if (test_params.magic0 != 0xdead || 1968c2ecf20Sopenharmony_ci test_params.magic1 != 0xbeef) 1978c2ecf20Sopenharmony_ci return 0; 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci test_case = test_params.tcase; 2008c2ecf20Sopenharmony_ci if (test_case != 3) 2018c2ecf20Sopenharmony_ci key = bpf_get_prandom_u32(); 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci if (test_case == 0) { 2048c2ecf20Sopenharmony_ci ret = bpf_map_update_elem(&lru_hash_map, &key, &val, BPF_ANY); 2058c2ecf20Sopenharmony_ci } else if (test_case == 1) { 2068c2ecf20Sopenharmony_ci ret = bpf_map_update_elem(&nocommon_lru_hash_map, &key, &val, 2078c2ecf20Sopenharmony_ci BPF_ANY); 2088c2ecf20Sopenharmony_ci } else if (test_case == 2) { 2098c2ecf20Sopenharmony_ci void *nolocal_lru_map; 2108c2ecf20Sopenharmony_ci int cpu = bpf_get_smp_processor_id(); 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ci nolocal_lru_map = bpf_map_lookup_elem(&array_of_lru_hashs, 2138c2ecf20Sopenharmony_ci &cpu); 2148c2ecf20Sopenharmony_ci if (!nolocal_lru_map) { 2158c2ecf20Sopenharmony_ci ret = -ENOENT; 2168c2ecf20Sopenharmony_ci goto done; 2178c2ecf20Sopenharmony_ci } 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci ret = bpf_map_update_elem(nolocal_lru_map, &key, &val, 2208c2ecf20Sopenharmony_ci BPF_ANY); 2218c2ecf20Sopenharmony_ci } else if (test_case == 3) { 2228c2ecf20Sopenharmony_ci u32 i; 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci key = test_params.key; 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci#pragma clang loop unroll(full) 2278c2ecf20Sopenharmony_ci for (i = 0; i < 32; i++) { 2288c2ecf20Sopenharmony_ci bpf_map_lookup_elem(&lru_hash_lookup_map, &key); 2298c2ecf20Sopenharmony_ci key++; 2308c2ecf20Sopenharmony_ci } 2318c2ecf20Sopenharmony_ci } else { 2328c2ecf20Sopenharmony_ci ret = -EINVAL; 2338c2ecf20Sopenharmony_ci } 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_cidone: 2368c2ecf20Sopenharmony_ci if (ret) 2378c2ecf20Sopenharmony_ci bpf_trace_printk(fmt, sizeof(fmt), ret); 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_ci return 0; 2408c2ecf20Sopenharmony_ci} 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_ciSEC("kprobe/" SYSCALL(sys_gettid)) 2438c2ecf20Sopenharmony_ciint stress_lpm_trie_map_alloc(struct pt_regs *ctx) 2448c2ecf20Sopenharmony_ci{ 2458c2ecf20Sopenharmony_ci union { 2468c2ecf20Sopenharmony_ci u32 b32[2]; 2478c2ecf20Sopenharmony_ci u8 b8[8]; 2488c2ecf20Sopenharmony_ci } key; 2498c2ecf20Sopenharmony_ci unsigned int i; 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_ci key.b32[0] = 32; 2528c2ecf20Sopenharmony_ci key.b8[4] = 192; 2538c2ecf20Sopenharmony_ci key.b8[5] = 168; 2548c2ecf20Sopenharmony_ci key.b8[6] = 0; 2558c2ecf20Sopenharmony_ci key.b8[7] = 1; 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ci#pragma clang loop unroll(full) 2588c2ecf20Sopenharmony_ci for (i = 0; i < 32; ++i) 2598c2ecf20Sopenharmony_ci bpf_map_lookup_elem(&lpm_trie_map_alloc, &key); 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_ci return 0; 2628c2ecf20Sopenharmony_ci} 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_ciSEC("kprobe/" SYSCALL(sys_getpgid)) 2658c2ecf20Sopenharmony_ciint stress_hash_map_lookup(struct pt_regs *ctx) 2668c2ecf20Sopenharmony_ci{ 2678c2ecf20Sopenharmony_ci u32 key = 1, i; 2688c2ecf20Sopenharmony_ci long *value; 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_ci#pragma clang loop unroll(full) 2718c2ecf20Sopenharmony_ci for (i = 0; i < 64; ++i) 2728c2ecf20Sopenharmony_ci value = bpf_map_lookup_elem(&hash_map, &key); 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci return 0; 2758c2ecf20Sopenharmony_ci} 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_ciSEC("kprobe/" SYSCALL(sys_getppid)) 2788c2ecf20Sopenharmony_ciint stress_array_map_lookup(struct pt_regs *ctx) 2798c2ecf20Sopenharmony_ci{ 2808c2ecf20Sopenharmony_ci u32 key = 1, i; 2818c2ecf20Sopenharmony_ci long *value; 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci#pragma clang loop unroll(full) 2848c2ecf20Sopenharmony_ci for (i = 0; i < 64; ++i) 2858c2ecf20Sopenharmony_ci value = bpf_map_lookup_elem(&array_map, &key); 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci return 0; 2888c2ecf20Sopenharmony_ci} 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_cichar _license[] SEC("license") = "GPL"; 2918c2ecf20Sopenharmony_ciu32 _version SEC("version") = LINUX_VERSION_CODE; 292