brintos

brintos / linux-shallow public Read only

0
0
Text · 4.0 KiB · b595556 Raw
166 lines · c
1// SPDX-License-Identifier: GPL-2.02 3#include <stdio.h>4#include <errno.h>5#include <string.h>6#include <unistd.h>7 8#include <bpf/bpf.h>9#include <bpf/libbpf.h>10 11#include <test_maps.h>12 13static int nr_cpus;14 15static void map_batch_update(int map_fd, __u32 max_entries, int *keys,16			     __s64 *values, bool is_pcpu)17{18	int i, j, err;19	int cpu_offset = 0;20	DECLARE_LIBBPF_OPTS(bpf_map_batch_opts, opts,21		.elem_flags = 0,22		.flags = 0,23	);24 25	for (i = 0; i < max_entries; i++) {26		keys[i] = i;27		if (is_pcpu) {28			cpu_offset = i * nr_cpus;29			for (j = 0; j < nr_cpus; j++)30				(values + cpu_offset)[j] = i + 1 + j;31		} else {32			values[i] = i + 1;33		}34	}35 36	err = bpf_map_update_batch(map_fd, keys, values, &max_entries, &opts);37	CHECK(err, "bpf_map_update_batch()", "error:%s\n", strerror(errno));38}39 40static void map_batch_verify(int *visited, __u32 max_entries, int *keys,41			     __s64 *values, bool is_pcpu)42{43	int i, j;44	int cpu_offset = 0;45 46	memset(visited, 0, max_entries * sizeof(*visited));47	for (i = 0; i < max_entries; i++) {48		if (is_pcpu) {49			cpu_offset = i * nr_cpus;50			for (j = 0; j < nr_cpus; j++) {51				__s64 value = (values + cpu_offset)[j];52				CHECK(keys[i] + j + 1 != value,53				      "key/value checking",54				      "error: i %d j %d key %d value %lld\n", i,55				      j, keys[i], value);56			}57		} else {58			CHECK(keys[i] + 1 != values[i], "key/value checking",59			      "error: i %d key %d value %lld\n", i, keys[i],60			      values[i]);61		}62		visited[i] = 1;63	}64	for (i = 0; i < max_entries; i++) {65		CHECK(visited[i] != 1, "visited checking",66		      "error: keys array at index %d missing\n", i);67	}68}69 70static void __test_map_lookup_and_update_batch(bool is_pcpu)71{72	int map_fd, *keys, *visited;73	__u32 count, total, total_success;74	const __u32 max_entries = 10;75	__u64 batch = 0;76	int err, step, value_size;77	void *values;78	DECLARE_LIBBPF_OPTS(bpf_map_batch_opts, opts,79		.elem_flags = 0,80		.flags = 0,81	);82 83	map_fd = bpf_map_create(is_pcpu ? BPF_MAP_TYPE_PERCPU_ARRAY : BPF_MAP_TYPE_ARRAY,84				"array_map", sizeof(int), sizeof(__s64), max_entries, NULL);85	CHECK(map_fd == -1,86	      "bpf_map_create()", "error:%s\n", strerror(errno));87 88	value_size = sizeof(__s64);89	if (is_pcpu)90		value_size *= nr_cpus;91 92	keys = calloc(max_entries, sizeof(*keys));93	values = calloc(max_entries, value_size);94	visited = calloc(max_entries, sizeof(*visited));95	CHECK(!keys || !values || !visited, "malloc()", "error:%s\n",96	      strerror(errno));97 98	/* test 1: lookup in a loop with various steps. */99	total_success = 0;100	for (step = 1; step < max_entries; step++) {101		map_batch_update(map_fd, max_entries, keys, values, is_pcpu);102		map_batch_verify(visited, max_entries, keys, values, is_pcpu);103		memset(keys, 0, max_entries * sizeof(*keys));104		memset(values, 0, max_entries * value_size);105		batch = 0;106		total = 0;107		/* iteratively lookup/delete elements with 'step'108		 * elements each.109		 */110		count = step;111		while (true) {112			err = bpf_map_lookup_batch(map_fd,113						   total ? &batch : NULL,114						   &batch, keys + total,115						   values + total * value_size,116						   &count, &opts);117 118			CHECK((err && errno != ENOENT), "lookup with steps",119			      "error: %s\n", strerror(errno));120 121			total += count;122			if (err)123				break;124 125		}126 127		CHECK(total != max_entries, "lookup with steps",128		      "total = %u, max_entries = %u\n", total, max_entries);129 130		map_batch_verify(visited, max_entries, keys, values, is_pcpu);131 132		total_success++;133	}134 135	CHECK(total_success == 0, "check total_success",136	      "unexpected failure\n");137 138	free(keys);139	free(values);140	free(visited);141	close(map_fd);142}143 144static void array_map_batch_ops(void)145{146	__test_map_lookup_and_update_batch(false);147	printf("test_%s:PASS\n", __func__);148}149 150static void array_percpu_map_batch_ops(void)151{152	__test_map_lookup_and_update_batch(true);153	printf("test_%s:PASS\n", __func__);154}155 156void test_array_map_batch_ops(void)157{158	nr_cpus = libbpf_num_possible_cpus();159 160	CHECK(nr_cpus < 0, "nr_cpus checking",161	      "error: get possible cpus failed");162 163	array_map_batch_ops();164	array_percpu_map_batch_ops();165}166