Skip to content

Commit b4abee7

Browse files
Benjamin TissoiresAlexei Starovoitov
authored andcommitted
selftests/bpf: add bpf_wq tests
We simply try in all supported map types if we can store/load a bpf_wq. Signed-off-by: Benjamin Tissoires <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 246331e commit b4abee7

File tree

2 files changed

+140
-0
lines changed
  • tools/testing/selftests/bpf

2 files changed

+140
-0
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* Copyright (c) 2024 Benjamin Tissoires */
3+
#include <test_progs.h>
4+
#include "wq.skel.h"
5+
6+
void serial_test_wq(void)
7+
{
8+
LIBBPF_OPTS(bpf_test_run_opts, topts);
9+
10+
RUN_TESTS(wq);
11+
}
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* Copyright (c) 2024 Benjamin Tissoires
3+
*/
4+
5+
#include "bpf_experimental.h"
6+
#include <bpf/bpf_helpers.h>
7+
#include "bpf_misc.h"
8+
#include "../bpf_testmod/bpf_testmod_kfunc.h"
9+
10+
char _license[] SEC("license") = "GPL";
11+
12+
struct hmap_elem {
13+
int counter;
14+
struct bpf_timer timer; /* unused */
15+
struct bpf_spin_lock lock; /* unused */
16+
struct bpf_wq work;
17+
};
18+
19+
struct {
20+
__uint(type, BPF_MAP_TYPE_HASH);
21+
__uint(max_entries, 1000);
22+
__type(key, int);
23+
__type(value, struct hmap_elem);
24+
} hmap SEC(".maps");
25+
26+
struct {
27+
__uint(type, BPF_MAP_TYPE_HASH);
28+
__uint(map_flags, BPF_F_NO_PREALLOC);
29+
__uint(max_entries, 1000);
30+
__type(key, int);
31+
__type(value, struct hmap_elem);
32+
} hmap_malloc SEC(".maps");
33+
34+
struct elem {
35+
struct bpf_wq w;
36+
};
37+
38+
struct {
39+
__uint(type, BPF_MAP_TYPE_ARRAY);
40+
__uint(max_entries, 2);
41+
__type(key, int);
42+
__type(value, struct elem);
43+
} array SEC(".maps");
44+
45+
struct {
46+
__uint(type, BPF_MAP_TYPE_LRU_HASH);
47+
__uint(max_entries, 4);
48+
__type(key, int);
49+
__type(value, struct elem);
50+
} lru SEC(".maps");
51+
52+
static int test_elem_callback(void *map, int *key)
53+
{
54+
struct elem init = {}, *val;
55+
56+
if (map == &lru &&
57+
bpf_map_update_elem(map, key, &init, 0))
58+
return -1;
59+
60+
val = bpf_map_lookup_elem(map, key);
61+
if (!val)
62+
return -2;
63+
64+
return 0;
65+
}
66+
67+
static int test_hmap_elem_callback(void *map, int *key)
68+
{
69+
struct hmap_elem init = {}, *val;
70+
71+
if (bpf_map_update_elem(map, key, &init, 0))
72+
return -1;
73+
74+
val = bpf_map_lookup_elem(map, key);
75+
if (!val)
76+
return -2;
77+
78+
return 0;
79+
}
80+
81+
SEC("tc")
82+
/* test that workqueues can be used from an array */
83+
__retval(0)
84+
long test_call_array_sleepable(void *ctx)
85+
{
86+
int key = 0;
87+
88+
return test_elem_callback(&array, &key);
89+
}
90+
91+
SEC("syscall")
92+
/* Same test than above but from a sleepable context. */
93+
__retval(0)
94+
long test_syscall_array_sleepable(void *ctx)
95+
{
96+
int key = 1;
97+
98+
return test_elem_callback(&array, &key);
99+
}
100+
101+
SEC("tc")
102+
/* test that workqueues can be used from a hashmap */
103+
__retval(0)
104+
long test_call_hash_sleepable(void *ctx)
105+
{
106+
int key = 2;
107+
108+
return test_hmap_elem_callback(&hmap, &key);
109+
}
110+
111+
SEC("tc")
112+
/* test that workqueues can be used from a hashmap with NO_PREALLOC. */
113+
__retval(0)
114+
long test_call_hash_malloc_sleepable(void *ctx)
115+
{
116+
int key = 3;
117+
118+
return test_hmap_elem_callback(&hmap_malloc, &key);
119+
}
120+
121+
SEC("tc")
122+
/* test that workqueues can be used from a LRU map */
123+
__retval(0)
124+
long test_call_lru_sleepable(void *ctx)
125+
{
126+
int key = 4;
127+
128+
return test_elem_callback(&lru, &key);
129+
}

0 commit comments

Comments
 (0)