139444Smsmith// SPDX-License-Identifier: GPL-2.0 239444Smsmith/* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */ 339444Smsmith 439444Smsmith#include "vmlinux.h" 539444Smsmith#include <bpf/bpf_helpers.h> 639444Smsmith#include "bpf_misc.h" 739444Smsmith 839444Smsmith#define HASHMAP_SZ 4194304 939444Smsmith 1039444Smsmithstruct { 1139444Smsmith __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS); 1239444Smsmith __uint(max_entries, 1000); 1339444Smsmith __type(key, int); 1439444Smsmith __type(value, int); 1539444Smsmith __array(values, struct { 1639444Smsmith __uint(type, BPF_MAP_TYPE_TASK_STORAGE); 1739444Smsmith __uint(map_flags, BPF_F_NO_PREALLOC); 1839444Smsmith __type(key, int); 1939444Smsmith __type(value, int); 2039444Smsmith }); 2139444Smsmith} array_of_local_storage_maps SEC(".maps"); 2239444Smsmith 2339444Smsmithstruct { 2439444Smsmith __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS); 2539444Smsmith __uint(max_entries, 1000); 2639444Smsmith __type(key, int); 2740597Smsmith __type(value, int); 2839444Smsmith __array(values, struct { 2939444Smsmith __uint(type, BPF_MAP_TYPE_HASH); 3039444Smsmith __uint(max_entries, HASHMAP_SZ); 3139444Smsmith __type(key, int); 3239444Smsmith __type(value, int); 3339444Smsmith }); 3439444Smsmith} array_of_hash_maps SEC(".maps"); 3539444Smsmith 3639444Smsmithlong important_hits; 3739444Smsmithlong hits; 3839444Smsmith 3939444Smsmith/* set from user-space */ 4039444Smsmithconst volatile unsigned int use_hashmap; 4139444Smsmithconst volatile unsigned int hashmap_num_keys; 4239444Smsmithconst volatile unsigned int num_maps; 4339444Smsmithconst volatile unsigned int interleave; 4439444Smsmith 4539444Smsmithstruct loop_ctx { 4640553Smsmith struct task_struct *task; 4740553Smsmith long loop_hits; 4839444Smsmith long loop_important_hits; 4939444Smsmith}; 5040597Smsmith 5139444Smsmithstatic int do_lookup(unsigned int elem, struct loop_ctx *lctx) 5239444Smsmith{ 5339444Smsmith void *map, *inner_map; 5439444Smsmith int idx = 0; 5539444Smsmith 5640553Smsmith if (use_hashmap) 5739444Smsmith map = &array_of_hash_maps; 5839444Smsmith else 5939444Smsmith map = &array_of_local_storage_maps; 6039444Smsmith 6139444Smsmith inner_map = bpf_map_lookup_elem(map, &elem); 6239444Smsmith if (!inner_map) 6339444Smsmith return -1; 6439444Smsmith 6539444Smsmith if (use_hashmap) { 6639444Smsmith idx = bpf_get_prandom_u32() % hashmap_num_keys; 6739444Smsmith bpf_map_lookup_elem(inner_map, &idx); 6839444Smsmith } else { 6939444Smsmith bpf_task_storage_get(inner_map, lctx->task, &idx, 7039444Smsmith BPF_LOCAL_STORAGE_GET_F_CREATE); 7140597Smsmith } 7239444Smsmith 7339444Smsmith lctx->loop_hits++; 7439444Smsmith if (!elem) 7539444Smsmith lctx->loop_important_hits++; 7639444Smsmith return 0; 7739444Smsmith} 7839444Smsmith 7939444Smsmithstatic long loop(u32 index, void *ctx) 8039444Smsmith{ 8139444Smsmith struct loop_ctx *lctx = (struct loop_ctx *)ctx; 8239444Smsmith unsigned int map_idx = index % num_maps; 8339444Smsmith 8439444Smsmith do_lookup(map_idx, lctx); 8539444Smsmith if (interleave && map_idx % 3 == 0) 8639444Smsmith do_lookup(0, lctx); 8739444Smsmith return 0; 8839444Smsmith} 8939444Smsmith 9039444SmsmithSEC("fentry/" SYS_PREFIX "sys_getpgid") 9139444Smsmithint get_local(void *ctx) 9239444Smsmith{ 9339444Smsmith struct loop_ctx lctx; 9439444Smsmith 9539444Smsmith lctx.task = bpf_get_current_task_btf(); 9639444Smsmith lctx.loop_hits = 0; 9739444Smsmith lctx.loop_important_hits = 0; 9839444Smsmith bpf_loop(10000, &loop, &lctx, 0); 9939444Smsmith __sync_add_and_fetch(&hits, lctx.loop_hits); 10039444Smsmith __sync_add_and_fetch(&important_hits, lctx.loop_important_hits); 10139444Smsmith return 0; 10239444Smsmith} 10339444Smsmith 10439444Smsmithchar _license[] SEC("license") = "GPL"; 10539444Smsmith