Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/bpf: Fix some bugs in map_lookup_percpu_elem testcase

comments from Andrii Nakryiko, details in here:
https://lore.kernel.org/lkml/20220511093854.411-1-zhoufeng.zf@bytedance.com/T/

use /* */ instead of //
use libbpf_num_possible_cpus() instead of sysconf(_SC_NPROCESSORS_ONLN)
use 8 bytes for value size
fix memory leak
use ASSERT_EQ instead of ASSERT_OK
add bpf_loop to fetch values on each possible CPU

Fixes: ed7c13776e20c74486b0939a3c1de984c5efb6aa ("selftests/bpf: add test case for bpf_map_lookup_percpu_elem")
Signed-off-by: Feng Zhou <zhoufeng.zf@bytedance.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Yonghong Song <yhs@fb.com>
Link: https://lore.kernel.org/bpf/20220518025053.20492-1-zhoufeng.zf@bytedance.com

authored by

Feng Zhou and committed by
Andrii Nakryiko
7aa424e0 834650b5

+73 -39
+30 -18
tools/testing/selftests/bpf/prog_tests/map_lookup_percpu_elem.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 - // Copyright (c) 2022 Bytedance 2 + /* Copyright (c) 2022 Bytedance */ 3 3 4 4 #include <test_progs.h> 5 - 6 5 #include "test_map_lookup_percpu_elem.skel.h" 7 - 8 - #define TEST_VALUE 1 9 6 10 7 void test_map_lookup_percpu_elem(void) 11 8 { 12 9 struct test_map_lookup_percpu_elem *skel; 13 - int key = 0, ret; 14 - int nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); 15 - int *buf; 10 + __u64 key = 0, sum; 11 + int ret, i, nr_cpus = libbpf_num_possible_cpus(); 12 + __u64 *buf; 16 13 17 - buf = (int *)malloc(nr_cpus*sizeof(int)); 14 + buf = malloc(nr_cpus*sizeof(__u64)); 18 15 if (!ASSERT_OK_PTR(buf, "malloc")) 19 16 return; 20 - memset(buf, 0, nr_cpus*sizeof(int)); 21 - buf[0] = TEST_VALUE; 22 17 23 - skel = test_map_lookup_percpu_elem__open_and_load(); 24 - if (!ASSERT_OK_PTR(skel, "test_map_lookup_percpu_elem__open_and_load")) 25 - return; 18 + for (i = 0; i < nr_cpus; i++) 19 + buf[i] = i; 20 + sum = (nr_cpus - 1) * nr_cpus / 2; 21 + 22 + skel = test_map_lookup_percpu_elem__open(); 23 + if (!ASSERT_OK_PTR(skel, "test_map_lookup_percpu_elem__open")) 24 + goto exit; 25 + 26 + skel->rodata->my_pid = getpid(); 27 + skel->rodata->nr_cpus = nr_cpus; 28 + 29 + ret = test_map_lookup_percpu_elem__load(skel); 30 + if (!ASSERT_OK(ret, "test_map_lookup_percpu_elem__load")) 31 + goto cleanup; 32 + 26 33 ret = test_map_lookup_percpu_elem__attach(skel); 27 - ASSERT_OK(ret, "test_map_lookup_percpu_elem__attach"); 34 + if (!ASSERT_OK(ret, "test_map_lookup_percpu_elem__attach")) 35 + goto cleanup; 28 36 29 37 ret = bpf_map_update_elem(bpf_map__fd(skel->maps.percpu_array_map), &key, buf, 0); 30 38 ASSERT_OK(ret, "percpu_array_map update"); ··· 45 37 46 38 syscall(__NR_getuid); 47 39 48 - ret = skel->bss->percpu_array_elem_val == TEST_VALUE && 49 - skel->bss->percpu_hash_elem_val == TEST_VALUE && 50 - skel->bss->percpu_lru_hash_elem_val == TEST_VALUE; 51 - ASSERT_OK(!ret, "bpf_map_lookup_percpu_elem success"); 40 + test_map_lookup_percpu_elem__detach(skel); 52 41 42 + ASSERT_EQ(skel->bss->percpu_array_elem_sum, sum, "percpu_array lookup percpu elem"); 43 + ASSERT_EQ(skel->bss->percpu_hash_elem_sum, sum, "percpu_hash lookup percpu elem"); 44 + ASSERT_EQ(skel->bss->percpu_lru_hash_elem_sum, sum, "percpu_lru_hash lookup percpu elem"); 45 + 46 + cleanup: 53 47 test_map_lookup_percpu_elem__destroy(skel); 48 + exit: 49 + free(buf); 54 50 }
+43 -21
tools/testing/selftests/bpf/progs/test_map_lookup_percpu_elem.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 - // Copyright (c) 2022 Bytedance 2 + /* Copyright (c) 2022 Bytedance */ 3 3 4 4 #include "vmlinux.h" 5 5 #include <bpf/bpf_helpers.h> 6 6 7 - int percpu_array_elem_val = 0; 8 - int percpu_hash_elem_val = 0; 9 - int percpu_lru_hash_elem_val = 0; 7 + __u64 percpu_array_elem_sum = 0; 8 + __u64 percpu_hash_elem_sum = 0; 9 + __u64 percpu_lru_hash_elem_sum = 0; 10 + const volatile int nr_cpus; 11 + const volatile int my_pid; 10 12 11 13 struct { 12 14 __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); 13 15 __uint(max_entries, 1); 14 16 __type(key, __u32); 15 - __type(value, __u32); 17 + __type(value, __u64); 16 18 } percpu_array_map SEC(".maps"); 17 19 18 20 struct { 19 21 __uint(type, BPF_MAP_TYPE_PERCPU_HASH); 20 22 __uint(max_entries, 1); 21 - __type(key, __u32); 22 - __type(value, __u32); 23 + __type(key, __u64); 24 + __type(value, __u64); 23 25 } percpu_hash_map SEC(".maps"); 24 26 25 27 struct { 26 28 __uint(type, BPF_MAP_TYPE_LRU_PERCPU_HASH); 27 29 __uint(max_entries, 1); 28 - __type(key, __u32); 29 - __type(value, __u32); 30 + __type(key, __u64); 31 + __type(value, __u64); 30 32 } percpu_lru_hash_map SEC(".maps"); 33 + 34 + struct read_percpu_elem_ctx { 35 + void *map; 36 + __u64 sum; 37 + }; 38 + 39 + static int read_percpu_elem_callback(__u32 index, struct read_percpu_elem_ctx *ctx) 40 + { 41 + __u64 key = 0; 42 + __u64 *value; 43 + 44 + value = bpf_map_lookup_percpu_elem(ctx->map, &key, index); 45 + if (value) 46 + ctx->sum += *value; 47 + return 0; 48 + } 31 49 32 50 SEC("tp/syscalls/sys_enter_getuid") 33 51 int sysenter_getuid(const void *ctx) 34 52 { 35 - __u32 key = 0; 36 - __u32 cpu = 0; 37 - __u32 *value; 53 + struct read_percpu_elem_ctx map_ctx; 38 54 39 - value = bpf_map_lookup_percpu_elem(&percpu_array_map, &key, cpu); 40 - if (value) 41 - percpu_array_elem_val = *value; 55 + if (my_pid != (bpf_get_current_pid_tgid() >> 32)) 56 + return 0; 42 57 43 - value = bpf_map_lookup_percpu_elem(&percpu_hash_map, &key, cpu); 44 - if (value) 45 - percpu_hash_elem_val = *value; 58 + map_ctx.map = &percpu_array_map; 59 + map_ctx.sum = 0; 60 + bpf_loop(nr_cpus, read_percpu_elem_callback, &map_ctx, 0); 61 + percpu_array_elem_sum = map_ctx.sum; 46 62 47 - value = bpf_map_lookup_percpu_elem(&percpu_lru_hash_map, &key, cpu); 48 - if (value) 49 - percpu_lru_hash_elem_val = *value; 63 + map_ctx.map = &percpu_hash_map; 64 + map_ctx.sum = 0; 65 + bpf_loop(nr_cpus, read_percpu_elem_callback, &map_ctx, 0); 66 + percpu_hash_elem_sum = map_ctx.sum; 67 + 68 + map_ctx.map = &percpu_lru_hash_map; 69 + map_ctx.sum = 0; 70 + bpf_loop(nr_cpus, read_percpu_elem_callback, &map_ctx, 0); 71 + percpu_lru_hash_elem_sum = map_ctx.sum; 50 72 51 73 return 0; 52 74 }