brintos

brintos / linux-shallow public Read only

0
0
Text · 7.2 KiB · a767bb4 Raw
292 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2 3#include <test_progs.h>4#include "test_lookup_and_delete.skel.h"5 6#define START_VALUE 12347#define NEW_VALUE 43218#define MAX_ENTRIES 29 10static int duration;11static int nr_cpus;12 13static int fill_values(int map_fd)14{15	__u64 key, value = START_VALUE;16	int err;17 18	for (key = 1; key < MAX_ENTRIES + 1; key++) {19		err = bpf_map_update_elem(map_fd, &key, &value, BPF_NOEXIST);20		if (!ASSERT_OK(err, "bpf_map_update_elem"))21			return -1;22	}23 24	return 0;25}26 27static int fill_values_percpu(int map_fd)28{29	__u64 key, value[nr_cpus];30	int i, err;31 32	for (i = 0; i < nr_cpus; i++)33		value[i] = START_VALUE;34 35	for (key = 1; key < MAX_ENTRIES + 1; key++) {36		err = bpf_map_update_elem(map_fd, &key, value, BPF_NOEXIST);37		if (!ASSERT_OK(err, "bpf_map_update_elem"))38			return -1;39	}40 41	return 0;42}43 44static struct test_lookup_and_delete *setup_prog(enum bpf_map_type map_type,45						 int *map_fd)46{47	struct test_lookup_and_delete *skel;48	int err;49 50	skel = test_lookup_and_delete__open();51	if (!ASSERT_OK_PTR(skel, "test_lookup_and_delete__open"))52		return NULL;53 54	err = bpf_map__set_type(skel->maps.hash_map, map_type);55	if (!ASSERT_OK(err, "bpf_map__set_type"))56		goto cleanup;57 58	err = bpf_map__set_max_entries(skel->maps.hash_map, MAX_ENTRIES);59	if (!ASSERT_OK(err, "bpf_map__set_max_entries"))60		goto cleanup;61 62	err = test_lookup_and_delete__load(skel);63	if (!ASSERT_OK(err, "test_lookup_and_delete__load"))64		goto cleanup;65 66	*map_fd = bpf_map__fd(skel->maps.hash_map);67	if (!ASSERT_GE(*map_fd, 0, "bpf_map__fd"))68		goto cleanup;69 70	return skel;71 72cleanup:73	test_lookup_and_delete__destroy(skel);74	return NULL;75}76 77/* Triggers BPF program that updates map with given key and value */78static int trigger_tp(struct test_lookup_and_delete *skel, __u64 key,79		      __u64 value)80{81	int err;82 83	skel->bss->set_pid = getpid();84	skel->bss->set_key = key;85	skel->bss->set_value = value;86 87	err = test_lookup_and_delete__attach(skel);88	if (!ASSERT_OK(err, "test_lookup_and_delete__attach"))89		return -1;90 91	syscall(__NR_getpgid);92 93	test_lookup_and_delete__detach(skel);94 95	return 0;96}97 98static void test_lookup_and_delete_hash(void)99{100	struct test_lookup_and_delete *skel;101	__u64 key, value;102	int map_fd, err;103 104	/* Setup program and fill the map. */105	skel = setup_prog(BPF_MAP_TYPE_HASH, &map_fd);106	if (!ASSERT_OK_PTR(skel, "setup_prog"))107		return;108 109	err = fill_values(map_fd);110	if (!ASSERT_OK(err, "fill_values"))111		goto cleanup;112 113	/* Lookup and delete element. */114	key = 1;115	err = bpf_map__lookup_and_delete_elem(skel->maps.hash_map,116					      &key, sizeof(key), &value, sizeof(value), 0);117	if (!ASSERT_OK(err, "bpf_map_lookup_and_delete_elem"))118		goto cleanup;119 120	/* Fetched value should match the initially set value. */121	if (CHECK(value != START_VALUE, "bpf_map_lookup_and_delete_elem",122		  "unexpected value=%lld\n", value))123		goto cleanup;124 125	/* Check that the entry is non existent. */126	err = bpf_map_lookup_elem(map_fd, &key, &value);127	if (!ASSERT_ERR(err, "bpf_map_lookup_elem"))128		goto cleanup;129 130cleanup:131	test_lookup_and_delete__destroy(skel);132}133 134static void test_lookup_and_delete_percpu_hash(void)135{136	struct test_lookup_and_delete *skel;137	__u64 key, val, value[nr_cpus];138	int map_fd, err, i;139 140	/* Setup program and fill the map. */141	skel = setup_prog(BPF_MAP_TYPE_PERCPU_HASH, &map_fd);142	if (!ASSERT_OK_PTR(skel, "setup_prog"))143		return;144 145	err = fill_values_percpu(map_fd);146	if (!ASSERT_OK(err, "fill_values_percpu"))147		goto cleanup;148 149	/* Lookup and delete element. */150	key = 1;151	err = bpf_map__lookup_and_delete_elem(skel->maps.hash_map,152					      &key, sizeof(key), value, sizeof(value), 0);153	if (!ASSERT_OK(err, "bpf_map_lookup_and_delete_elem"))154		goto cleanup;155 156	for (i = 0; i < nr_cpus; i++) {157		val = value[i];158 159		/* Fetched value should match the initially set value. */160		if (CHECK(val != START_VALUE, "map value",161			  "unexpected for cpu %d: %lld\n", i, val))162			goto cleanup;163	}164 165	/* Check that the entry is non existent. */166	err = bpf_map_lookup_elem(map_fd, &key, value);167	if (!ASSERT_ERR(err, "bpf_map_lookup_elem"))168		goto cleanup;169 170cleanup:171	test_lookup_and_delete__destroy(skel);172}173 174static void test_lookup_and_delete_lru_hash(void)175{176	struct test_lookup_and_delete *skel;177	__u64 key, value;178	int map_fd, err;179 180	/* Setup program and fill the LRU map. */181	skel = setup_prog(BPF_MAP_TYPE_LRU_HASH, &map_fd);182	if (!ASSERT_OK_PTR(skel, "setup_prog"))183		return;184 185	err = fill_values(map_fd);186	if (!ASSERT_OK(err, "fill_values"))187		goto cleanup;188 189	/* Insert new element at key=3, should reuse LRU element. */190	key = 3;191	err = trigger_tp(skel, key, NEW_VALUE);192	if (!ASSERT_OK(err, "trigger_tp"))193		goto cleanup;194 195	/* Lookup and delete element 3. */196	err = bpf_map__lookup_and_delete_elem(skel->maps.hash_map,197					      &key, sizeof(key), &value, sizeof(value), 0);198	if (!ASSERT_OK(err, "bpf_map_lookup_and_delete_elem"))199		goto cleanup;200 201	/* Value should match the new value. */202	if (CHECK(value != NEW_VALUE, "bpf_map_lookup_and_delete_elem",203		  "unexpected value=%lld\n", value))204		goto cleanup;205 206	/* Check that entries 3 and 1 are non existent. */207	err = bpf_map_lookup_elem(map_fd, &key, &value);208	if (!ASSERT_ERR(err, "bpf_map_lookup_elem"))209		goto cleanup;210 211	key = 1;212	err = bpf_map_lookup_elem(map_fd, &key, &value);213	if (!ASSERT_ERR(err, "bpf_map_lookup_elem"))214		goto cleanup;215 216cleanup:217	test_lookup_and_delete__destroy(skel);218}219 220static void test_lookup_and_delete_lru_percpu_hash(void)221{222	struct test_lookup_and_delete *skel;223	__u64 key, val, value[nr_cpus];224	int map_fd, err, i, cpucnt = 0;225 226	/* Setup program and fill the LRU map. */227	skel = setup_prog(BPF_MAP_TYPE_LRU_PERCPU_HASH, &map_fd);228	if (!ASSERT_OK_PTR(skel, "setup_prog"))229		return;230 231	err = fill_values_percpu(map_fd);232	if (!ASSERT_OK(err, "fill_values_percpu"))233		goto cleanup;234 235	/* Insert new element at key=3, should reuse LRU element 1. */236	key = 3;237	err = trigger_tp(skel, key, NEW_VALUE);238	if (!ASSERT_OK(err, "trigger_tp"))239		goto cleanup;240 241	/* Clean value. */242	for (i = 0; i < nr_cpus; i++)243		value[i] = 0;244 245	/* Lookup and delete element 3. */246	err = bpf_map__lookup_and_delete_elem(skel->maps.hash_map,247					      &key, sizeof(key), value, sizeof(value), 0);248	if (!ASSERT_OK(err, "bpf_map_lookup_and_delete_elem"))249		goto cleanup;250 251	/* Check if only one CPU has set the value. */252	for (i = 0; i < nr_cpus; i++) {253		val = value[i];254		if (val) {255			if (CHECK(val != NEW_VALUE, "map value",256				  "unexpected for cpu %d: %lld\n", i, val))257				goto cleanup;258			cpucnt++;259		}260	}261	if (CHECK(cpucnt != 1, "map value", "set for %d CPUs instead of 1!\n",262		  cpucnt))263		goto cleanup;264 265	/* Check that entries 3 and 1 are non existent. */266	err = bpf_map_lookup_elem(map_fd, &key, &value);267	if (!ASSERT_ERR(err, "bpf_map_lookup_elem"))268		goto cleanup;269 270	key = 1;271	err = bpf_map_lookup_elem(map_fd, &key, &value);272	if (!ASSERT_ERR(err, "bpf_map_lookup_elem"))273		goto cleanup;274 275cleanup:276	test_lookup_and_delete__destroy(skel);277}278 279void test_lookup_and_delete(void)280{281	nr_cpus = bpf_num_possible_cpus();282 283	if (test__start_subtest("lookup_and_delete"))284		test_lookup_and_delete_hash();285	if (test__start_subtest("lookup_and_delete_percpu"))286		test_lookup_and_delete_percpu_hash();287	if (test__start_subtest("lookup_and_delete_lru"))288		test_lookup_and_delete_lru_hash();289	if (test__start_subtest("lookup_and_delete_lru_percpu"))290		test_lookup_and_delete_lru_percpu_hash();291}292