162306a36Sopenharmony_ci/* Copyright (c) 2016 Facebook 262306a36Sopenharmony_ci * 362306a36Sopenharmony_ci * This program is free software; you can redistribute it and/or 462306a36Sopenharmony_ci * modify it under the terms of version 2 of the GNU General Public 562306a36Sopenharmony_ci * License as published by the Free Software Foundation. 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci#include "vmlinux.h" 862306a36Sopenharmony_ci#include <errno.h> 962306a36Sopenharmony_ci#include <linux/version.h> 1062306a36Sopenharmony_ci#include <bpf/bpf_helpers.h> 1162306a36Sopenharmony_ci#include <bpf/bpf_tracing.h> 1262306a36Sopenharmony_ci#include <bpf/bpf_core_read.h> 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#define MAX_ENTRIES 1000 1562306a36Sopenharmony_ci#define MAX_NR_CPUS 1024 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_cistruct { 1862306a36Sopenharmony_ci __uint(type, BPF_MAP_TYPE_HASH); 1962306a36Sopenharmony_ci __type(key, u32); 2062306a36Sopenharmony_ci __type(value, long); 2162306a36Sopenharmony_ci __uint(max_entries, MAX_ENTRIES); 2262306a36Sopenharmony_ci} hash_map SEC(".maps"); 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_cistruct { 2562306a36Sopenharmony_ci __uint(type, BPF_MAP_TYPE_LRU_HASH); 2662306a36Sopenharmony_ci __type(key, u32); 2762306a36Sopenharmony_ci __type(value, long); 2862306a36Sopenharmony_ci __uint(max_entries, 10000); 2962306a36Sopenharmony_ci} lru_hash_map SEC(".maps"); 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_cistruct { 3262306a36Sopenharmony_ci __uint(type, BPF_MAP_TYPE_LRU_HASH); 3362306a36Sopenharmony_ci __type(key, u32); 3462306a36Sopenharmony_ci __type(value, long); 3562306a36Sopenharmony_ci __uint(max_entries, 10000); 3662306a36Sopenharmony_ci __uint(map_flags, BPF_F_NO_COMMON_LRU); 3762306a36Sopenharmony_ci} nocommon_lru_hash_map SEC(".maps"); 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_cistruct inner_lru { 4062306a36Sopenharmony_ci __uint(type, BPF_MAP_TYPE_LRU_HASH); 4162306a36Sopenharmony_ci __type(key, u32); 4262306a36Sopenharmony_ci __type(value, long); 4362306a36Sopenharmony_ci __uint(max_entries, MAX_ENTRIES); 4462306a36Sopenharmony_ci __uint(map_flags, BPF_F_NUMA_NODE); 4562306a36Sopenharmony_ci __uint(numa_node, 0); 4662306a36Sopenharmony_ci} inner_lru_hash_map SEC(".maps"); 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_cistruct { 4962306a36Sopenharmony_ci __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS); 5062306a36Sopenharmony_ci __uint(max_entries, MAX_NR_CPUS); 5162306a36Sopenharmony_ci __uint(key_size, sizeof(u32)); 5262306a36Sopenharmony_ci __array(values, struct inner_lru); /* use inner_lru as inner map */ 5362306a36Sopenharmony_ci} array_of_lru_hashs SEC(".maps") = { 5462306a36Sopenharmony_ci /* statically initialize the first element */ 5562306a36Sopenharmony_ci .values = { &inner_lru_hash_map }, 5662306a36Sopenharmony_ci}; 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_cistruct { 5962306a36Sopenharmony_ci __uint(type, BPF_MAP_TYPE_PERCPU_HASH); 6062306a36Sopenharmony_ci __uint(key_size, sizeof(u32)); 6162306a36Sopenharmony_ci __uint(value_size, sizeof(long)); 6262306a36Sopenharmony_ci __uint(max_entries, MAX_ENTRIES); 6362306a36Sopenharmony_ci} percpu_hash_map SEC(".maps"); 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_cistruct { 6662306a36Sopenharmony_ci __uint(type, BPF_MAP_TYPE_HASH); 6762306a36Sopenharmony_ci __type(key, u32); 6862306a36Sopenharmony_ci __type(value, long); 6962306a36Sopenharmony_ci __uint(max_entries, MAX_ENTRIES); 7062306a36Sopenharmony_ci __uint(map_flags, BPF_F_NO_PREALLOC); 7162306a36Sopenharmony_ci} hash_map_alloc SEC(".maps"); 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_cistruct { 7462306a36Sopenharmony_ci __uint(type, BPF_MAP_TYPE_PERCPU_HASH); 7562306a36Sopenharmony_ci __uint(key_size, sizeof(u32)); 7662306a36Sopenharmony_ci __uint(value_size, sizeof(long)); 7762306a36Sopenharmony_ci __uint(max_entries, MAX_ENTRIES); 7862306a36Sopenharmony_ci __uint(map_flags, BPF_F_NO_PREALLOC); 7962306a36Sopenharmony_ci} percpu_hash_map_alloc SEC(".maps"); 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_cistruct { 8262306a36Sopenharmony_ci __uint(type, BPF_MAP_TYPE_LPM_TRIE); 8362306a36Sopenharmony_ci __uint(key_size, 8); 8462306a36Sopenharmony_ci __uint(value_size, sizeof(long)); 8562306a36Sopenharmony_ci __uint(max_entries, 10000); 8662306a36Sopenharmony_ci __uint(map_flags, BPF_F_NO_PREALLOC); 8762306a36Sopenharmony_ci} lpm_trie_map_alloc SEC(".maps"); 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_cistruct { 9062306a36Sopenharmony_ci __uint(type, BPF_MAP_TYPE_ARRAY); 9162306a36Sopenharmony_ci __type(key, u32); 9262306a36Sopenharmony_ci __type(value, long); 9362306a36Sopenharmony_ci __uint(max_entries, MAX_ENTRIES); 9462306a36Sopenharmony_ci} array_map SEC(".maps"); 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_cistruct { 9762306a36Sopenharmony_ci __uint(type, BPF_MAP_TYPE_LRU_HASH); 9862306a36Sopenharmony_ci __type(key, u32); 9962306a36Sopenharmony_ci __type(value, long); 10062306a36Sopenharmony_ci __uint(max_entries, MAX_ENTRIES); 10162306a36Sopenharmony_ci} lru_hash_lookup_map SEC(".maps"); 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ciSEC("ksyscall/getuid") 10462306a36Sopenharmony_ciint BPF_KSYSCALL(stress_hmap) 10562306a36Sopenharmony_ci{ 10662306a36Sopenharmony_ci u32 key = bpf_get_current_pid_tgid(); 10762306a36Sopenharmony_ci long init_val = 1; 10862306a36Sopenharmony_ci long *value; 10962306a36Sopenharmony_ci int i; 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci for (i = 0; i < 10; i++) { 11262306a36Sopenharmony_ci bpf_map_update_elem(&hash_map, &key, &init_val, BPF_ANY); 11362306a36Sopenharmony_ci value = bpf_map_lookup_elem(&hash_map, &key); 11462306a36Sopenharmony_ci if (value) 11562306a36Sopenharmony_ci bpf_map_delete_elem(&hash_map, &key); 11662306a36Sopenharmony_ci } 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci return 0; 11962306a36Sopenharmony_ci} 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ciSEC("ksyscall/geteuid") 12262306a36Sopenharmony_ciint BPF_KSYSCALL(stress_percpu_hmap) 12362306a36Sopenharmony_ci{ 12462306a36Sopenharmony_ci u32 key = bpf_get_current_pid_tgid(); 12562306a36Sopenharmony_ci long init_val = 1; 12662306a36Sopenharmony_ci long *value; 12762306a36Sopenharmony_ci int i; 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci for (i = 0; i < 10; i++) { 13062306a36Sopenharmony_ci bpf_map_update_elem(&percpu_hash_map, &key, &init_val, BPF_ANY); 13162306a36Sopenharmony_ci value = bpf_map_lookup_elem(&percpu_hash_map, &key); 13262306a36Sopenharmony_ci if (value) 13362306a36Sopenharmony_ci bpf_map_delete_elem(&percpu_hash_map, &key); 13462306a36Sopenharmony_ci } 13562306a36Sopenharmony_ci return 0; 13662306a36Sopenharmony_ci} 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ciSEC("ksyscall/getgid") 13962306a36Sopenharmony_ciint BPF_KSYSCALL(stress_hmap_alloc) 14062306a36Sopenharmony_ci{ 14162306a36Sopenharmony_ci u32 key = bpf_get_current_pid_tgid(); 14262306a36Sopenharmony_ci long init_val = 1; 14362306a36Sopenharmony_ci long *value; 14462306a36Sopenharmony_ci int i; 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci for (i = 0; i < 10; i++) { 14762306a36Sopenharmony_ci bpf_map_update_elem(&hash_map_alloc, &key, &init_val, BPF_ANY); 14862306a36Sopenharmony_ci value = bpf_map_lookup_elem(&hash_map_alloc, &key); 14962306a36Sopenharmony_ci if (value) 15062306a36Sopenharmony_ci bpf_map_delete_elem(&hash_map_alloc, &key); 15162306a36Sopenharmony_ci } 15262306a36Sopenharmony_ci return 0; 15362306a36Sopenharmony_ci} 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ciSEC("ksyscall/getegid") 15662306a36Sopenharmony_ciint BPF_KSYSCALL(stress_percpu_hmap_alloc) 15762306a36Sopenharmony_ci{ 15862306a36Sopenharmony_ci u32 key = bpf_get_current_pid_tgid(); 15962306a36Sopenharmony_ci long init_val = 1; 16062306a36Sopenharmony_ci long *value; 16162306a36Sopenharmony_ci int i; 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci for (i = 0; i < 10; i++) { 16462306a36Sopenharmony_ci bpf_map_update_elem(&percpu_hash_map_alloc, &key, &init_val, BPF_ANY); 16562306a36Sopenharmony_ci value = bpf_map_lookup_elem(&percpu_hash_map_alloc, &key); 16662306a36Sopenharmony_ci if (value) 16762306a36Sopenharmony_ci bpf_map_delete_elem(&percpu_hash_map_alloc, &key); 16862306a36Sopenharmony_ci } 16962306a36Sopenharmony_ci return 0; 17062306a36Sopenharmony_ci} 17162306a36Sopenharmony_ciSEC("ksyscall/connect") 17262306a36Sopenharmony_ciint BPF_KSYSCALL(stress_lru_hmap_alloc, int fd, struct sockaddr_in *uservaddr, 17362306a36Sopenharmony_ci int addrlen) 17462306a36Sopenharmony_ci{ 17562306a36Sopenharmony_ci char fmt[] = "Failed at stress_lru_hmap_alloc. ret:%dn"; 17662306a36Sopenharmony_ci union { 17762306a36Sopenharmony_ci u16 dst6[8]; 17862306a36Sopenharmony_ci struct { 17962306a36Sopenharmony_ci u16 magic0; 18062306a36Sopenharmony_ci u16 magic1; 18162306a36Sopenharmony_ci u16 tcase; 18262306a36Sopenharmony_ci u16 unused16; 18362306a36Sopenharmony_ci u32 unused32; 18462306a36Sopenharmony_ci u32 key; 18562306a36Sopenharmony_ci }; 18662306a36Sopenharmony_ci } test_params; 18762306a36Sopenharmony_ci struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)uservaddr; 18862306a36Sopenharmony_ci u16 test_case; 18962306a36Sopenharmony_ci long val = 1; 19062306a36Sopenharmony_ci u32 key = 0; 19162306a36Sopenharmony_ci int ret; 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci if (addrlen != sizeof(*in6)) 19462306a36Sopenharmony_ci return 0; 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci ret = bpf_probe_read_user(test_params.dst6, sizeof(test_params.dst6), 19762306a36Sopenharmony_ci &in6->sin6_addr); 19862306a36Sopenharmony_ci if (ret) 19962306a36Sopenharmony_ci goto done; 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci if (test_params.magic0 != 0xdead || 20262306a36Sopenharmony_ci test_params.magic1 != 0xbeef) 20362306a36Sopenharmony_ci return 0; 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci test_case = test_params.tcase; 20662306a36Sopenharmony_ci if (test_case != 3) 20762306a36Sopenharmony_ci key = bpf_get_prandom_u32(); 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci if (test_case == 0) { 21062306a36Sopenharmony_ci ret = bpf_map_update_elem(&lru_hash_map, &key, &val, BPF_ANY); 21162306a36Sopenharmony_ci } else if (test_case == 1) { 21262306a36Sopenharmony_ci ret = bpf_map_update_elem(&nocommon_lru_hash_map, &key, &val, 21362306a36Sopenharmony_ci BPF_ANY); 21462306a36Sopenharmony_ci } else if (test_case == 2) { 21562306a36Sopenharmony_ci void *nolocal_lru_map; 21662306a36Sopenharmony_ci int cpu = bpf_get_smp_processor_id(); 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ci nolocal_lru_map = bpf_map_lookup_elem(&array_of_lru_hashs, 21962306a36Sopenharmony_ci &cpu); 22062306a36Sopenharmony_ci if (!nolocal_lru_map) { 22162306a36Sopenharmony_ci ret = -ENOENT; 22262306a36Sopenharmony_ci goto done; 22362306a36Sopenharmony_ci } 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci ret = bpf_map_update_elem(nolocal_lru_map, &key, &val, 22662306a36Sopenharmony_ci BPF_ANY); 22762306a36Sopenharmony_ci } else if (test_case == 3) { 22862306a36Sopenharmony_ci u32 i; 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci key = test_params.key; 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci#pragma clang loop unroll(full) 23362306a36Sopenharmony_ci for (i = 0; i < 32; i++) { 23462306a36Sopenharmony_ci bpf_map_lookup_elem(&lru_hash_lookup_map, &key); 23562306a36Sopenharmony_ci key++; 23662306a36Sopenharmony_ci } 23762306a36Sopenharmony_ci } else { 23862306a36Sopenharmony_ci ret = -EINVAL; 23962306a36Sopenharmony_ci } 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_cidone: 24262306a36Sopenharmony_ci if (ret) 24362306a36Sopenharmony_ci bpf_trace_printk(fmt, sizeof(fmt), ret); 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ci return 0; 24662306a36Sopenharmony_ci} 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ciSEC("ksyscall/gettid") 24962306a36Sopenharmony_ciint BPF_KSYSCALL(stress_lpm_trie_map_alloc) 25062306a36Sopenharmony_ci{ 25162306a36Sopenharmony_ci union { 25262306a36Sopenharmony_ci u32 b32[2]; 25362306a36Sopenharmony_ci u8 b8[8]; 25462306a36Sopenharmony_ci } key; 25562306a36Sopenharmony_ci unsigned int i; 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_ci key.b32[0] = 32; 25862306a36Sopenharmony_ci key.b8[4] = 192; 25962306a36Sopenharmony_ci key.b8[5] = 168; 26062306a36Sopenharmony_ci key.b8[6] = 0; 26162306a36Sopenharmony_ci key.b8[7] = 1; 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci#pragma clang loop unroll(full) 26462306a36Sopenharmony_ci for (i = 0; i < 32; ++i) 26562306a36Sopenharmony_ci bpf_map_lookup_elem(&lpm_trie_map_alloc, &key); 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci return 0; 26862306a36Sopenharmony_ci} 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ciSEC("ksyscall/getpgid") 27162306a36Sopenharmony_ciint BPF_KSYSCALL(stress_hash_map_lookup) 27262306a36Sopenharmony_ci{ 27362306a36Sopenharmony_ci u32 key = 1, i; 27462306a36Sopenharmony_ci long *value; 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci#pragma clang loop unroll(full) 27762306a36Sopenharmony_ci for (i = 0; i < 64; ++i) 27862306a36Sopenharmony_ci value = bpf_map_lookup_elem(&hash_map, &key); 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci return 0; 28162306a36Sopenharmony_ci} 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ciSEC("ksyscall/getppid") 28462306a36Sopenharmony_ciint BPF_KSYSCALL(stress_array_map_lookup) 28562306a36Sopenharmony_ci{ 28662306a36Sopenharmony_ci u32 key = 1, i; 28762306a36Sopenharmony_ci long *value; 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_ci#pragma clang loop unroll(full) 29062306a36Sopenharmony_ci for (i = 0; i < 64; ++i) 29162306a36Sopenharmony_ci value = bpf_map_lookup_elem(&array_map, &key); 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci return 0; 29462306a36Sopenharmony_ci} 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_cichar _license[] SEC("license") = "GPL"; 29762306a36Sopenharmony_ciu32 _version SEC("version") = LINUX_VERSION_CODE; 298