FILE
lpm_trie_map_get_next_key.c
File preview with syntax highlighting.
linux-6.19.14/tools/testing/selftests/bpf/map_tests/lpm_trie_map_get_next_key.c
1// SPDX-License-Identifier: GPL-2.0 2 3#define _GNU_SOURCE 4#include <linux/bpf.h> 5#include <stdio.h> 6#include <stdbool.h> 7#include <unistd.h> 8#include <errno.h> 9#include <stdlib.h> 10#include <string.h> 11#include <pthread.h> 12 13#include <bpf/bpf.h> 14#include <bpf/libbpf.h> 15 16#include <test_maps.h> 17 18struct test_lpm_key { 19 __u32 prefix; 20 __u32 data; 21}; 22 23struct get_next_key_ctx { 24 struct test_lpm_key key; 25 bool start; 26 bool stop; 27 int map_fd; 28 int loop; 29}; 30 31static void *get_next_key_fn(void *arg) 32{ 33 struct get_next_key_ctx *ctx = arg; 34 struct test_lpm_key next_key; 35 int i = 0; 36 37 while (!ctx->start) 38 usleep(1); 39 40 while (!ctx->stop && i++ < ctx->loop) 41 bpf_map_get_next_key(ctx->map_fd, &ctx->key, &next_key); 42 43 return NULL; 44} 45 46static void abort_get_next_key(struct get_next_key_ctx *ctx, pthread_t *tids, 47 unsigned int nr) 48{ 49 unsigned int i; 50 51 ctx->stop = true; 52 ctx->start = true; 53 for (i = 0; i < nr; i++) 54 pthread_join(tids[i], NULL); 55} 56 57/* This test aims to prevent regression of future. As long as the kernel does 58 * not panic, it is considered as success. 59 */ 60void test_lpm_trie_map_get_next_key(void) 61{ 62#define MAX_NR_THREADS 8 63 LIBBPF_OPTS(bpf_map_create_opts, create_opts, 64 .map_flags = BPF_F_NO_PREALLOC); 65 struct test_lpm_key key = {}; 66 __u32 val = 0; 67 int map_fd; 68 const __u32 max_prefixlen = 8 * (sizeof(key) - sizeof(key.prefix)); 69 const __u32 max_entries = max_prefixlen + 1; 70 unsigned int i, nr = MAX_NR_THREADS, loop = 65536; 71 pthread_t tids[MAX_NR_THREADS]; 72 struct get_next_key_ctx ctx; 73 int err; 74 75 map_fd = bpf_map_create(BPF_MAP_TYPE_LPM_TRIE, "lpm_trie_map", 76 sizeof(struct test_lpm_key), sizeof(__u32), 77 max_entries, &create_opts); 78 CHECK(map_fd == -1, "bpf_map_create()", "error:%s\n", 79 strerror(errno)); 80 81 for (i = 0; i <= max_prefixlen; i++) { 82 key.prefix = i; 83 err = bpf_map_update_elem(map_fd, &key, &val, BPF_ANY); 84 CHECK(err, "bpf_map_update_elem()", "error:%s\n", 85 strerror(errno)); 86 } 87 88 ctx.start = false; 89 ctx.stop = false; 90 ctx.map_fd = map_fd; 91 ctx.loop = loop; 92 memcpy(&ctx.key, &key, sizeof(key)); 93 94 for (i = 0; i < nr; i++) { 95 err = pthread_create(&tids[i], NULL, get_next_key_fn, &ctx); 96 if (err) { 97 abort_get_next_key(&ctx, tids, i); 98 CHECK(err, "pthread_create", "error %d\n", err); 99 } 100 } 101 102 ctx.start = true; 103 for (i = 0; i < nr; i++) 104 pthread_join(tids[i], NULL); 105 106 printf("%s:PASS\n", __func__); 107 108 close(map_fd); 109}
~/
Read-only file preview.