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