1 // SPDX-License-Identifier: GPL-2.0 2 #include <test_progs.h> 3 4 static void *parallel_map_access(void *arg) 5 { 6 int err, map_fd = *(u32 *) arg; 7 int vars[17], i, j, rnd, key = 0; 8 9 for (i = 0; i < 10000; i++) { 10 err = bpf_map_lookup_elem_flags(map_fd, &key, vars, BPF_F_LOCK); 11 if (CHECK_FAIL(err)) { 12 printf("lookup failed\n"); 13 goto out; 14 } 15 if (CHECK_FAIL(vars[0] != 0)) { 16 printf("lookup #%d var[0]=%d\n", i, vars[0]); 17 goto out; 18 } 19 rnd = vars[1]; 20 for (j = 2; j < 17; j++) { 21 if (vars[j] == rnd) 22 continue; 23 printf("lookup #%d var[1]=%d var[%d]=%d\n", 24 i, rnd, j, vars[j]); 25 CHECK_FAIL(vars[j] != rnd); 26 goto out; 27 } 28 } 29 out: 30 pthread_exit(arg); 31 } 32 33 void test_map_lock(void) 34 { 35 const char *file = "./test_map_lock.o"; 36 int prog_fd, map_fd[2], vars[17] = {}; 37 pthread_t thread_id[6]; 38 struct bpf_object *obj = NULL; 39 int err = 0, key = 0, i; 40 void *ret; 41 42 err = bpf_prog_load(file, BPF_PROG_TYPE_CGROUP_SKB, &obj, &prog_fd); 43 if (CHECK_FAIL(err)) { 44 printf("test_map_lock:bpf_prog_load errno %d\n", errno); 45 goto close_prog; 46 } 47 map_fd[0] = bpf_find_map(__func__, obj, "hash_map"); 48 if (CHECK_FAIL(map_fd[0] < 0)) 49 goto close_prog; 50 map_fd[1] = bpf_find_map(__func__, obj, "array_map"); 51 if (CHECK_FAIL(map_fd[1] < 0)) 52 goto close_prog; 53 54 bpf_map_update_elem(map_fd[0], &key, vars, BPF_F_LOCK); 55 56 for (i = 0; i < 4; i++) 57 if (CHECK_FAIL(pthread_create(&thread_id[i], NULL, 58 &spin_lock_thread, &prog_fd))) 59 goto close_prog; 60 for (i = 4; i < 6; i++) 61 if (CHECK_FAIL(pthread_create(&thread_id[i], NULL, 62 ¶llel_map_access, 63 &map_fd[i - 4]))) 64 goto close_prog; 65 for (i = 0; i < 4; i++) 66 if (CHECK_FAIL(pthread_join(thread_id[i], &ret) || 67 ret != (void *)&prog_fd)) 68 goto close_prog; 69 for (i = 4; i < 6; i++) 70 if (CHECK_FAIL(pthread_join(thread_id[i], &ret) || 71 ret != (void *)&map_fd[i - 4])) 72 goto close_prog; 73 close_prog: 74 bpf_object__close(obj); 75 } 76