diff mbox series

[bpf-next,v2,10/16] selftests/bpf: add bpf_wq tests

Message ID 20240420-bpf_wq-v2-10-6c986a5a741f@kernel.org (mailing list archive)
State Accepted
Commit b4abee7c1ae3d59440e7915da28c6d2cd394738a
Headers show
Series Introduce bpf_wq | expand

Commit Message

Benjamin Tissoires April 20, 2024, 9:09 a.m. UTC
We simply try in all supported map types if we can store/load a bpf_wq.

Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>

---

no changes in v2
---
 tools/testing/selftests/bpf/prog_tests/wq.c |  11 +++
 tools/testing/selftests/bpf/progs/wq.c      | 135 ++++++++++++++++++++++++++++
 2 files changed, 146 insertions(+)

Comments

Alexei Starovoitov April 24, 2024, 2:56 a.m. UTC | #1
On Sat, Apr 20, 2024 at 2:10 AM Benjamin Tissoires <bentiss@kernel.org> wrote:
>
> +
> +SEC("tc")
> +/* test that workqueues can be used from an array
> + */
> +__retval(0)
> +long test_call_array_sleepable(void *ctx)
> +{
> +       int key = 0;
> +
> +       return test_elem_callback(&array, &key);
> +}
> +
> +SEC("syscall")
> +/* Same test than above but from a sleepable context.
> + */

I adjusted all these comments to be normal single line comments.

The main thing to follow up is to figure out how to wait for wq
to finish.
Since we have this message:
./test_progs -t wq
...
#521     wq:OK
Summary: 2/9 PASSED, 0 SKIPPED, 0 FAILED
Failed to unload bpf_testmod.ko from kernel: -11

and doing manual "rmmod bpf_testmod"
after the test run is quite annoying.

Overall great stuff. Thank you for pushing it through.
Much appreciated!
Alexei Starovoitov April 24, 2024, 9:07 p.m. UTC | #2
On Tue, Apr 23, 2024 at 7:56 PM Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
>
> On Sat, Apr 20, 2024 at 2:10 AM Benjamin Tissoires <bentiss@kernel.org> wrote:
> >
> > +
> > +SEC("tc")
> > +/* test that workqueues can be used from an array
> > + */
> > +__retval(0)
> > +long test_call_array_sleepable(void *ctx)
> > +{
> > +       int key = 0;
> > +
> > +       return test_elem_callback(&array, &key);
> > +}
> > +
> > +SEC("syscall")
> > +/* Same test than above but from a sleepable context.
> > + */
>
> I adjusted all these comments to be normal single line comments.
>
> The main thing to follow up is to figure out how to wait for wq
> to finish.
> Since we have this message:
> ./test_progs -t wq
> ...
> #521     wq:OK
> Summary: 2/9 PASSED, 0 SKIPPED, 0 FAILED
> Failed to unload bpf_testmod.ko from kernel: -11
>
> and doing manual "rmmod bpf_testmod"
> after the test run is quite annoying.
>
> Overall great stuff. Thank you for pushing it through.
> Much appreciated!

Hi Benjamin,

I've ended up fixing it as well,
because it was causing CI issues.

See
https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/commit/?id=82e38a505c9868e784ec31e743fd8a9fa5ca1084
diff mbox series

Patch

diff --git a/tools/testing/selftests/bpf/prog_tests/wq.c b/tools/testing/selftests/bpf/prog_tests/wq.c
new file mode 100644
index 000000000000..9a07b8bc2c52
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/wq.c
@@ -0,0 +1,11 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2024 Benjamin Tissoires */
+#include <test_progs.h>
+#include "wq.skel.h"
+
+void serial_test_wq(void)
+{
+	LIBBPF_OPTS(bpf_test_run_opts, topts);
+
+	RUN_TESTS(wq);
+}
diff --git a/tools/testing/selftests/bpf/progs/wq.c b/tools/testing/selftests/bpf/progs/wq.c
new file mode 100644
index 000000000000..8c668ad04059
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/wq.c
@@ -0,0 +1,135 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2024 Benjamin Tissoires
+ */
+
+#include "bpf_experimental.h"
+#include <bpf/bpf_helpers.h>
+#include "bpf_misc.h"
+#include "../bpf_testmod/bpf_testmod_kfunc.h"
+
+char _license[] SEC("license") = "GPL";
+
+struct hmap_elem {
+	int counter;
+	struct bpf_timer timer; /* unused */
+	struct bpf_spin_lock lock; /* unused */
+	struct bpf_wq work;
+};
+
+struct {
+	__uint(type, BPF_MAP_TYPE_HASH);
+	__uint(max_entries, 1000);
+	__type(key, int);
+	__type(value, struct hmap_elem);
+} hmap SEC(".maps");
+
+struct {
+	__uint(type, BPF_MAP_TYPE_HASH);
+	__uint(map_flags, BPF_F_NO_PREALLOC);
+	__uint(max_entries, 1000);
+	__type(key, int);
+	__type(value, struct hmap_elem);
+} hmap_malloc SEC(".maps");
+
+struct elem {
+	struct bpf_wq w;
+};
+
+struct {
+	__uint(type, BPF_MAP_TYPE_ARRAY);
+	__uint(max_entries, 2);
+	__type(key, int);
+	__type(value, struct elem);
+} array SEC(".maps");
+
+struct {
+	__uint(type, BPF_MAP_TYPE_LRU_HASH);
+	__uint(max_entries, 4);
+	__type(key, int);
+	__type(value, struct elem);
+} lru SEC(".maps");
+
+static int test_elem_callback(void *map, int *key)
+{
+	struct elem init = {}, *val;
+
+	if (map == &lru &&
+	    bpf_map_update_elem(map, key, &init, 0))
+		return -1;
+
+	val = bpf_map_lookup_elem(map, key);
+	if (!val)
+		return -2;
+
+	return 0;
+}
+
+static int test_hmap_elem_callback(void *map, int *key)
+{
+	struct hmap_elem init = {}, *val;
+
+	if (bpf_map_update_elem(map, key, &init, 0))
+		return -1;
+
+	val = bpf_map_lookup_elem(map, key);
+	if (!val)
+		return -2;
+
+	return 0;
+}
+
+SEC("tc")
+/* test that workqueues can be used from an array
+ */
+__retval(0)
+long test_call_array_sleepable(void *ctx)
+{
+	int key = 0;
+
+	return test_elem_callback(&array, &key);
+}
+
+SEC("syscall")
+/* Same test than above but from a sleepable context.
+ */
+__retval(0)
+long test_syscall_array_sleepable(void *ctx)
+{
+	int key = 1;
+
+	return test_elem_callback(&array, &key);
+}
+
+SEC("tc")
+/* test that workqueues can be used from a hashmap
+ */
+__retval(0)
+long test_call_hash_sleepable(void *ctx)
+{
+	int key = 2;
+
+	return test_hmap_elem_callback(&hmap, &key);
+}
+
+SEC("tc")
+/* test that workqueues can be used from a hashmap
+ * with NO_PREALLOC.
+ */
+__retval(0)
+long test_call_hash_malloc_sleepable(void *ctx)
+{
+	int key = 3;
+
+	return test_hmap_elem_callback(&hmap_malloc, &key);
+}
+
+SEC("tc")
+/* test that workqueues can be used from a LRU map
+ */
+__retval(0)
+long test_call_lru_sleepable(void *ctx)
+{
+	int key = 4;
+
+	return test_elem_callback(&lru, &key);
+}