File Index
Files and directories
Sign in
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 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.