linux/samples/bpf/map_perf_test_kern.c
<<
>>
Prefs
   1/* Copyright (c) 2016 Facebook
   2 *
   3 * This program is free software; you can redistribute it and/or
   4 * modify it under the terms of version 2 of the GNU General Public
   5 * License as published by the Free Software Foundation.
   6 */
   7#include <linux/skbuff.h>
   8#include <linux/netdevice.h>
   9#include <linux/version.h>
  10#include <uapi/linux/bpf.h>
  11#include "bpf_helpers.h"
  12
  13#define MAX_ENTRIES 1000
  14#define MAX_NR_CPUS 1024
  15
  16struct bpf_map_def SEC("maps") hash_map = {
  17        .type = BPF_MAP_TYPE_HASH,
  18        .key_size = sizeof(u32),
  19        .value_size = sizeof(long),
  20        .max_entries = MAX_ENTRIES,
  21};
  22
  23struct bpf_map_def SEC("maps") lru_hash_map = {
  24        .type = BPF_MAP_TYPE_LRU_HASH,
  25        .key_size = sizeof(u32),
  26        .value_size = sizeof(long),
  27        .max_entries = 10000,
  28};
  29
  30struct bpf_map_def SEC("maps") nocommon_lru_hash_map = {
  31        .type = BPF_MAP_TYPE_LRU_HASH,
  32        .key_size = sizeof(u32),
  33        .value_size = sizeof(long),
  34        .max_entries = 10000,
  35        .map_flags = BPF_F_NO_COMMON_LRU,
  36};
  37
  38struct bpf_map_def SEC("maps") inner_lru_hash_map = {
  39        .type = BPF_MAP_TYPE_LRU_HASH,
  40        .key_size = sizeof(u32),
  41        .value_size = sizeof(long),
  42        .max_entries = MAX_ENTRIES,
  43};
  44
  45struct bpf_map_def SEC("maps") array_of_lru_hashs = {
  46        .type = BPF_MAP_TYPE_ARRAY_OF_MAPS,
  47        .key_size = sizeof(u32),
  48        .max_entries = MAX_NR_CPUS,
  49};
  50
  51struct bpf_map_def SEC("maps") percpu_hash_map = {
  52        .type = BPF_MAP_TYPE_PERCPU_HASH,
  53        .key_size = sizeof(u32),
  54        .value_size = sizeof(long),
  55        .max_entries = MAX_ENTRIES,
  56};
  57
  58struct bpf_map_def SEC("maps") hash_map_alloc = {
  59        .type = BPF_MAP_TYPE_HASH,
  60        .key_size = sizeof(u32),
  61        .value_size = sizeof(long),
  62        .max_entries = MAX_ENTRIES,
  63        .map_flags = BPF_F_NO_PREALLOC,
  64};
  65
  66struct bpf_map_def SEC("maps") percpu_hash_map_alloc = {
  67        .type = BPF_MAP_TYPE_PERCPU_HASH,
  68        .key_size = sizeof(u32),
  69        .value_size = sizeof(long),
  70        .max_entries = MAX_ENTRIES,
  71        .map_flags = BPF_F_NO_PREALLOC,
  72};
  73
  74struct bpf_map_def SEC("maps") lpm_trie_map_alloc = {
  75        .type = BPF_MAP_TYPE_LPM_TRIE,
  76        .key_size = 8,
  77        .value_size = sizeof(long),
  78        .max_entries = 10000,
  79        .map_flags = BPF_F_NO_PREALLOC,
  80};
  81
  82struct bpf_map_def SEC("maps") array_map = {
  83        .type = BPF_MAP_TYPE_ARRAY,
  84        .key_size = sizeof(u32),
  85        .value_size = sizeof(long),
  86        .max_entries = MAX_ENTRIES,
  87};
  88
  89SEC("kprobe/sys_getuid")
  90int stress_hmap(struct pt_regs *ctx)
  91{
  92        u32 key = bpf_get_current_pid_tgid();
  93        long init_val = 1;
  94        long *value;
  95
  96        bpf_map_update_elem(&hash_map, &key, &init_val, BPF_ANY);
  97        value = bpf_map_lookup_elem(&hash_map, &key);
  98        if (value)
  99                bpf_map_delete_elem(&hash_map, &key);
 100
 101        return 0;
 102}
 103
 104SEC("kprobe/sys_geteuid")
 105int stress_percpu_hmap(struct pt_regs *ctx)
 106{
 107        u32 key = bpf_get_current_pid_tgid();
 108        long init_val = 1;
 109        long *value;
 110
 111        bpf_map_update_elem(&percpu_hash_map, &key, &init_val, BPF_ANY);
 112        value = bpf_map_lookup_elem(&percpu_hash_map, &key);
 113        if (value)
 114                bpf_map_delete_elem(&percpu_hash_map, &key);
 115        return 0;
 116}
 117
 118SEC("kprobe/sys_getgid")
 119int stress_hmap_alloc(struct pt_regs *ctx)
 120{
 121        u32 key = bpf_get_current_pid_tgid();
 122        long init_val = 1;
 123        long *value;
 124
 125        bpf_map_update_elem(&hash_map_alloc, &key, &init_val, BPF_ANY);
 126        value = bpf_map_lookup_elem(&hash_map_alloc, &key);
 127        if (value)
 128                bpf_map_delete_elem(&hash_map_alloc, &key);
 129        return 0;
 130}
 131
 132SEC("kprobe/sys_getegid")
 133int stress_percpu_hmap_alloc(struct pt_regs *ctx)
 134{
 135        u32 key = bpf_get_current_pid_tgid();
 136        long init_val = 1;
 137        long *value;
 138
 139        bpf_map_update_elem(&percpu_hash_map_alloc, &key, &init_val, BPF_ANY);
 140        value = bpf_map_lookup_elem(&percpu_hash_map_alloc, &key);
 141        if (value)
 142                bpf_map_delete_elem(&percpu_hash_map_alloc, &key);
 143        return 0;
 144}
 145
 146SEC("kprobe/sys_connect")
 147int stress_lru_hmap_alloc(struct pt_regs *ctx)
 148{
 149        struct sockaddr_in6 *in6;
 150        u16 test_case, dst6[8];
 151        int addrlen, ret;
 152        char fmt[] = "Failed at stress_lru_hmap_alloc. ret:%d\n";
 153        long val = 1;
 154        u32 key = bpf_get_prandom_u32();
 155
 156        in6 = (struct sockaddr_in6 *)PT_REGS_PARM2(ctx);
 157        addrlen = (int)PT_REGS_PARM3(ctx);
 158
 159        if (addrlen != sizeof(*in6))
 160                return 0;
 161
 162        ret = bpf_probe_read(dst6, sizeof(dst6), &in6->sin6_addr);
 163        if (ret)
 164                goto done;
 165
 166        if (dst6[0] != 0xdead || dst6[1] != 0xbeef)
 167                return 0;
 168
 169        test_case = dst6[7];
 170
 171        if (test_case == 0) {
 172                ret = bpf_map_update_elem(&lru_hash_map, &key, &val, BPF_ANY);
 173        } else if (test_case == 1) {
 174                ret = bpf_map_update_elem(&nocommon_lru_hash_map, &key, &val,
 175                                          BPF_ANY);
 176        } else if (test_case == 2) {
 177                void *nolocal_lru_map;
 178                int cpu = bpf_get_smp_processor_id();
 179
 180                nolocal_lru_map = bpf_map_lookup_elem(&array_of_lru_hashs,
 181                                                      &cpu);
 182                if (!nolocal_lru_map) {
 183                        ret = -ENOENT;
 184                        goto done;
 185                }
 186
 187                ret = bpf_map_update_elem(nolocal_lru_map, &key, &val,
 188                                          BPF_ANY);
 189        } else {
 190                ret = -EINVAL;
 191        }
 192
 193done:
 194        if (ret)
 195                bpf_trace_printk(fmt, sizeof(fmt), ret);
 196
 197        return 0;
 198}
 199
 200SEC("kprobe/sys_gettid")
 201int stress_lpm_trie_map_alloc(struct pt_regs *ctx)
 202{
 203        union {
 204                u32 b32[2];
 205                u8 b8[8];
 206        } key;
 207        unsigned int i;
 208
 209        key.b32[0] = 32;
 210        key.b8[4] = 192;
 211        key.b8[5] = 168;
 212        key.b8[6] = 0;
 213        key.b8[7] = 1;
 214
 215#pragma clang loop unroll(full)
 216        for (i = 0; i < 32; ++i)
 217                bpf_map_lookup_elem(&lpm_trie_map_alloc, &key);
 218
 219        return 0;
 220}
 221
 222SEC("kprobe/sys_getpgid")
 223int stress_hash_map_lookup(struct pt_regs *ctx)
 224{
 225        u32 key = 1, i;
 226        long *value;
 227
 228#pragma clang loop unroll(full)
 229        for (i = 0; i < 64; ++i)
 230                value = bpf_map_lookup_elem(&hash_map, &key);
 231
 232        return 0;
 233}
 234
 235SEC("kprobe/sys_getpgrp")
 236int stress_array_map_lookup(struct pt_regs *ctx)
 237{
 238        u32 key = 1, i;
 239        long *value;
 240
 241#pragma clang loop unroll(full)
 242        for (i = 0; i < 64; ++i)
 243                value = bpf_map_lookup_elem(&array_map, &key);
 244
 245        return 0;
 246}
 247
 248char _license[] SEC("license") = "GPL";
 249u32 _version SEC("version") = LINUX_VERSION_CODE;
 250