Skip to content

Commit e155967

Browse files
iamkafaidavem330
authored andcommitted
samples/bpf: unit test for BPF_MAP_TYPE_PERCPU_HASH
A sanity test for BPF_MAP_TYPE_PERCPU_HASH. Signed-off-by: Martin KaFai Lau <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 15a07b3 commit e155967

File tree

1 file changed

+96
-0
lines changed

1 file changed

+96
-0
lines changed

samples/bpf/test_maps.c

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,100 @@ static void test_hashmap_sanity(int i, void *data)
8989
close(map_fd);
9090
}
9191

92+
/* sanity tests for percpu map API */
93+
static void test_percpu_hashmap_sanity(int task, void *data)
94+
{
95+
long long key, next_key;
96+
int expected_key_mask = 0;
97+
unsigned int nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
98+
long long value[nr_cpus];
99+
int map_fd, i;
100+
101+
map_fd = bpf_create_map(BPF_MAP_TYPE_PERCPU_HASH, sizeof(key),
102+
sizeof(value[0]), 2);
103+
if (map_fd < 0) {
104+
printf("failed to create hashmap '%s'\n", strerror(errno));
105+
exit(1);
106+
}
107+
108+
for (i = 0; i < nr_cpus; i++)
109+
value[i] = i + 100;
110+
key = 1;
111+
/* insert key=1 element */
112+
assert(!(expected_key_mask & key));
113+
assert(bpf_update_elem(map_fd, &key, value, BPF_ANY) == 0);
114+
expected_key_mask |= key;
115+
116+
/* BPF_NOEXIST means: add new element if it doesn't exist */
117+
assert(bpf_update_elem(map_fd, &key, value, BPF_NOEXIST) == -1 &&
118+
/* key=1 already exists */
119+
errno == EEXIST);
120+
121+
/* -1 is an invalid flag */
122+
assert(bpf_update_elem(map_fd, &key, value, -1) == -1 &&
123+
errno == EINVAL);
124+
125+
/* check that key=1 can be found. value could be 0 if the lookup
126+
* was run from a different cpu.
127+
*/
128+
value[0] = 1;
129+
assert(bpf_lookup_elem(map_fd, &key, value) == 0 && value[0] == 100);
130+
131+
key = 2;
132+
/* check that key=2 is not found */
133+
assert(bpf_lookup_elem(map_fd, &key, value) == -1 && errno == ENOENT);
134+
135+
/* BPF_EXIST means: update existing element */
136+
assert(bpf_update_elem(map_fd, &key, value, BPF_EXIST) == -1 &&
137+
/* key=2 is not there */
138+
errno == ENOENT);
139+
140+
/* insert key=2 element */
141+
assert(!(expected_key_mask & key));
142+
assert(bpf_update_elem(map_fd, &key, value, BPF_NOEXIST) == 0);
143+
expected_key_mask |= key;
144+
145+
/* key=1 and key=2 were inserted, check that key=0 cannot be inserted
146+
* due to max_entries limit
147+
*/
148+
key = 0;
149+
assert(bpf_update_elem(map_fd, &key, value, BPF_NOEXIST) == -1 &&
150+
errno == E2BIG);
151+
152+
/* check that key = 0 doesn't exist */
153+
assert(bpf_delete_elem(map_fd, &key) == -1 && errno == ENOENT);
154+
155+
/* iterate over two elements */
156+
while (!bpf_get_next_key(map_fd, &key, &next_key)) {
157+
assert((expected_key_mask & next_key) == next_key);
158+
expected_key_mask &= ~next_key;
159+
160+
assert(bpf_lookup_elem(map_fd, &next_key, value) == 0);
161+
for (i = 0; i < nr_cpus; i++)
162+
assert(value[i] == i + 100);
163+
164+
key = next_key;
165+
}
166+
assert(errno == ENOENT);
167+
168+
/* Update with BPF_EXIST */
169+
key = 1;
170+
assert(bpf_update_elem(map_fd, &key, value, BPF_EXIST) == 0);
171+
172+
/* delete both elements */
173+
key = 1;
174+
assert(bpf_delete_elem(map_fd, &key) == 0);
175+
key = 2;
176+
assert(bpf_delete_elem(map_fd, &key) == 0);
177+
assert(bpf_delete_elem(map_fd, &key) == -1 && errno == ENOENT);
178+
179+
key = 0;
180+
/* check that map is empty */
181+
assert(bpf_get_next_key(map_fd, &key, &next_key) == -1 &&
182+
errno == ENOENT);
183+
close(map_fd);
184+
}
185+
92186
static void test_arraymap_sanity(int i, void *data)
93187
{
94188
int key, next_key, map_fd;
@@ -209,6 +303,7 @@ static void run_parallel(int tasks, void (*fn)(int i, void *data), void *data)
209303
static void test_map_stress(void)
210304
{
211305
run_parallel(100, test_hashmap_sanity, NULL);
306+
run_parallel(100, test_percpu_hashmap_sanity, NULL);
212307
run_parallel(100, test_arraymap_sanity, NULL);
213308
}
214309

@@ -282,6 +377,7 @@ static void test_map_parallel(void)
282377
int main(void)
283378
{
284379
test_hashmap_sanity(0, NULL);
380+
test_percpu_hashmap_sanity(0, NULL);
285381
test_arraymap_sanity(0, NULL);
286382
test_map_large();
287383
test_map_parallel();

0 commit comments

Comments
 (0)