diff mbox series

[bpf-next,2/2] Added selftests to check deadlocks in queue and stack map

Message ID 20240429165658.1305969-2-sidchintamaneni@gmail.com (mailing list archive)
State Changes Requested
Delegated to: BPF
Headers show
Series [bpf-next,1/2] Patch to Fix deadlocks in queue and stack maps | expand

Checks

Context Check Description
bpf/vmtest-bpf-next-PR fail PR summary
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for bpf-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 949 this patch: 949
netdev/build_tools success Errors and warnings before: 0 this patch: 0
netdev/cc_maintainers warning 11 maintainers not CCed: kpsingh@kernel.org john.fastabend@gmail.com shuah@kernel.org jolsa@kernel.org eddyz87@gmail.com song@kernel.org linux-kselftest@vger.kernel.org martin.lau@linux.dev mykolal@fb.com haoluo@google.com sdf@google.com
netdev/build_clang success Errors and warnings before: 955 this patch: 955
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 961 this patch: 961
netdev/checkpatch warning CHECK: Blank lines aren't necessary before a close brace '}' CHECK: Please don't use multiple blank lines WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-next-VM_Test-0 success Logs for Lint
bpf/vmtest-bpf-next-VM_Test-1 success Logs for ShellCheck
bpf/vmtest-bpf-next-VM_Test-2 success Logs for Unittests
bpf/vmtest-bpf-next-VM_Test-3 success Logs for Validate matrix.py
bpf/vmtest-bpf-next-VM_Test-5 success Logs for aarch64-gcc / build-release
bpf/vmtest-bpf-next-VM_Test-4 success Logs for aarch64-gcc / build / build for aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-10 success Logs for aarch64-gcc / veristat
bpf/vmtest-bpf-next-VM_Test-12 success Logs for s390x-gcc / build-release
bpf/vmtest-bpf-next-VM_Test-11 success Logs for s390x-gcc / build / build for s390x with gcc
bpf/vmtest-bpf-next-VM_Test-17 success Logs for s390x-gcc / veristat
bpf/vmtest-bpf-next-VM_Test-18 success Logs for set-matrix
bpf/vmtest-bpf-next-VM_Test-19 success Logs for x86_64-gcc / build / build for x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-20 success Logs for x86_64-gcc / build-release
bpf/vmtest-bpf-next-VM_Test-29 success Logs for x86_64-llvm-17 / build-release / build for x86_64 with llvm-17 and -O2 optimization
bpf/vmtest-bpf-next-VM_Test-28 success Logs for x86_64-llvm-17 / build / build for x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-34 success Logs for x86_64-llvm-17 / veristat
bpf/vmtest-bpf-next-VM_Test-35 success Logs for x86_64-llvm-18 / build / build for x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-36 success Logs for x86_64-llvm-18 / build-release / build for x86_64 with llvm-18 and -O2 optimization
bpf/vmtest-bpf-next-VM_Test-42 success Logs for x86_64-llvm-18 / veristat
bpf/vmtest-bpf-next-VM_Test-6 fail Logs for aarch64-gcc / test (test_maps, false, 360) / test_maps on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-9 success Logs for aarch64-gcc / test (test_verifier, false, 360) / test_verifier on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-13 fail Logs for s390x-gcc / test (test_maps, false, 360) / test_maps on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-16 success Logs for s390x-gcc / test (test_verifier, false, 360) / test_verifier on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-8 fail Logs for aarch64-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-7 fail Logs for aarch64-gcc / test (test_progs, false, 360) / test_progs on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-14 fail Logs for s390x-gcc / test (test_progs, false, 360) / test_progs on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-15 fail Logs for s390x-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-26 success Logs for x86_64-gcc / test (test_verifier, false, 360) / test_verifier on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-27 success Logs for x86_64-gcc / veristat / veristat on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-24 success Logs for x86_64-gcc / test (test_progs_no_alu32_parallel, true, 30) / test_progs_no_alu32_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-41 success Logs for x86_64-llvm-18 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-30 fail Logs for x86_64-llvm-17 / test (test_maps, false, 360) / test_maps on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-33 success Logs for x86_64-llvm-17 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-37 fail Logs for x86_64-llvm-18 / test (test_maps, false, 360) / test_maps on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-25 success Logs for x86_64-gcc / test (test_progs_parallel, true, 30) / test_progs_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-21 fail Logs for x86_64-gcc / test (test_maps, false, 360) / test_maps on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-23 fail Logs for x86_64-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-38 fail Logs for x86_64-llvm-18 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-32 fail Logs for x86_64-llvm-17 / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-22 fail Logs for x86_64-gcc / test (test_progs, false, 360) / test_progs on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-39 fail Logs for x86_64-llvm-18 / test (test_progs_cpuv4, false, 360) / test_progs_cpuv4 on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-31 fail Logs for x86_64-llvm-17 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-40 fail Logs for x86_64-llvm-18 / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with llvm-18

Commit Message

Siddharth Chintamaneni April 29, 2024, 4:56 p.m. UTC
From: Siddharth Chintamaneni <sidchintamaneni@vt.edu>

 Added selftests to check for nested deadlocks in queue
 and stack maps.

Signed-off-by: Siddharth Chintamaneni <sidchintamaneni@vt.edu>
---
 .../prog_tests/test_queue_stack_nested_map.c  | 48 ++++++++++++++
 .../bpf/progs/test_queue_stack_nested_map.c   | 62 +++++++++++++++++++
 2 files changed, 110 insertions(+)
 create mode 100644 tools/testing/selftests/bpf/prog_tests/test_queue_stack_nested_map.c
 create mode 100644 tools/testing/selftests/bpf/progs/test_queue_stack_nested_map.c

Comments

Kumar Kartikeya Dwivedi April 29, 2024, 5:54 p.m. UTC | #1
On Mon, 29 Apr 2024 at 18:57, Siddharth Chintamaneni
<sidchintamaneni@gmail.com> wrote:
>
> From: Siddharth Chintamaneni <sidchintamaneni@vt.edu>
>
>  Added selftests to check for nested deadlocks in queue
>  and stack maps.
>
> Signed-off-by: Siddharth Chintamaneni <sidchintamaneni@vt.edu>
> ---

Forgot to remind in the previous reply, but:
For the patch subject, use 'bpf:' prefix for kernel patches, and
'selftests/bpf:' for selftests, see the commit logs in bpf-next for
examples.

>  .../prog_tests/test_queue_stack_nested_map.c  | 48 ++++++++++++++
>  .../bpf/progs/test_queue_stack_nested_map.c   | 62 +++++++++++++++++++
>  2 files changed, 110 insertions(+)
>  create mode 100644 tools/testing/selftests/bpf/prog_tests/test_queue_stack_nested_map.c
>  create mode 100644 tools/testing/selftests/bpf/progs/test_queue_stack_nested_map.c
>
> diff --git a/tools/testing/selftests/bpf/prog_tests/test_queue_stack_nested_map.c b/tools/testing/selftests/bpf/prog_tests/test_queue_stack_nested_map.c
> new file mode 100644
> index 000000000000..731e958419eb
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/prog_tests/test_queue_stack_nested_map.c
> @@ -0,0 +1,48 @@
> +// SPDX-License-Identifier: GPL-2.0
> +#include <test_progs.h>
> +#include <network_helpers.h>
> +
> +#include "test_queue_stack_nested_map.skel.h"
> +
> +
> +static void test_map_queue_stack_nesting_success(bool is_map_queue)
> +{
> +       struct test_queue_stack_nested_map *skel;
> +       int err;
> +       int prog_fd;
> +
> +       LIBBPF_OPTS(bpf_test_run_opts, ropts);
> +
> +       skel = test_queue_stack_nested_map__open_and_load();
> +       if (!ASSERT_OK_PTR(skel, "test_queue_stack_nested_map__open_and_load"))
> +               goto out;
> +
> +       err = test_queue_stack_nested_map__attach(skel);
> +       if (!ASSERT_OK(err, "test_queue_stack_nested_map__attach"))
> +               goto out;
> +
> +       if (is_map_queue) {
> +               prog_fd = bpf_program__fd(skel->progs.test_queue_nesting);
> +               err = bpf_prog_test_run_opts(prog_fd, &ropts);
> +               ASSERT_OK(err, "test_nested_queue_map_run");

Maybe you can also check the ropts.optval to ensure we get -EBUSY?
I.e. return the value of map push/pop from the program and then check
it here?
It can be set in a global variable from the program triggering the
deadlock, and then you could return the value back as the return value
of the program.
If fentry has restrictions on the return code, you could try other
program types which work in test_run_opts (like SEC("tc")), there are
many examples in selftests using such programs.

> [...]
>
>
Siddharth Chintamaneni April 29, 2024, 6:07 p.m. UTC | #2
On Mon, 29 Apr 2024 at 13:55, Kumar Kartikeya Dwivedi <memxor@gmail.com> wrote:
>
> On Mon, 29 Apr 2024 at 18:57, Siddharth Chintamaneni
> <sidchintamaneni@gmail.com> wrote:
> >
> > From: Siddharth Chintamaneni <sidchintamaneni@vt.edu>
> >
> >  Added selftests to check for nested deadlocks in queue
> >  and stack maps.
> >
> > Signed-off-by: Siddharth Chintamaneni <sidchintamaneni@vt.edu>
> > ---
>
> Forgot to remind in the previous reply, but:
> For the patch subject, use 'bpf:' prefix for kernel patches, and
> 'selftests/bpf:' for selftests, see the commit logs in bpf-next for
> examples.

Thanks, I will do that in the revision.

>
> >  .../prog_tests/test_queue_stack_nested_map.c  | 48 ++++++++++++++
> >  .../bpf/progs/test_queue_stack_nested_map.c   | 62 +++++++++++++++++++
> >  2 files changed, 110 insertions(+)
> >  create mode 100644 tools/testing/selftests/bpf/prog_tests/test_queue_stack_nested_map.c
> >  create mode 100644 tools/testing/selftests/bpf/progs/test_queue_stack_nested_map.c
> >
> > diff --git a/tools/testing/selftests/bpf/prog_tests/test_queue_stack_nested_map.c b/tools/testing/selftests/bpf/prog_tests/test_queue_stack_nested_map.c
> > new file mode 100644
> > index 000000000000..731e958419eb
> > --- /dev/null
> > +++ b/tools/testing/selftests/bpf/prog_tests/test_queue_stack_nested_map.c
> > @@ -0,0 +1,48 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +#include <test_progs.h>
> > +#include <network_helpers.h>
> > +
> > +#include "test_queue_stack_nested_map.skel.h"
> > +
> > +
> > +static void test_map_queue_stack_nesting_success(bool is_map_queue)
> > +{
> > +       struct test_queue_stack_nested_map *skel;
> > +       int err;
> > +       int prog_fd;
> > +
> > +       LIBBPF_OPTS(bpf_test_run_opts, ropts);
> > +
> > +       skel = test_queue_stack_nested_map__open_and_load();
> > +       if (!ASSERT_OK_PTR(skel, "test_queue_stack_nested_map__open_and_load"))
> > +               goto out;
> > +
> > +       err = test_queue_stack_nested_map__attach(skel);
> > +       if (!ASSERT_OK(err, "test_queue_stack_nested_map__attach"))
> > +               goto out;
> > +
> > +       if (is_map_queue) {
> > +               prog_fd = bpf_program__fd(skel->progs.test_queue_nesting);
> > +               err = bpf_prog_test_run_opts(prog_fd, &ropts);
> > +               ASSERT_OK(err, "test_nested_queue_map_run");
>
> Maybe you can also check the ropts.optval to ensure we get -EBUSY?
> I.e. return the value of map push/pop from the program and then check
> it here?

make sense.I will do that.

> It can be set in a global variable from the program triggering the
> deadlock, and then you could return the value back as the return value
> of the program.
> If fentry has restrictions on the return code, you could try other
> program types which work in test_run_opts (like SEC("tc")), there are
> many examples in selftests using such programs.
>
> > [...]
> >
> >
diff mbox series

Patch

diff --git a/tools/testing/selftests/bpf/prog_tests/test_queue_stack_nested_map.c b/tools/testing/selftests/bpf/prog_tests/test_queue_stack_nested_map.c
new file mode 100644
index 000000000000..731e958419eb
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/test_queue_stack_nested_map.c
@@ -0,0 +1,48 @@ 
+// SPDX-License-Identifier: GPL-2.0
+#include <test_progs.h>
+#include <network_helpers.h>
+
+#include "test_queue_stack_nested_map.skel.h"
+
+
+static void test_map_queue_stack_nesting_success(bool is_map_queue)
+{
+	struct test_queue_stack_nested_map *skel;
+	int err;
+	int prog_fd;
+
+	LIBBPF_OPTS(bpf_test_run_opts, ropts);
+
+	skel = test_queue_stack_nested_map__open_and_load();
+	if (!ASSERT_OK_PTR(skel, "test_queue_stack_nested_map__open_and_load"))
+		goto out;
+
+	err = test_queue_stack_nested_map__attach(skel);
+	if (!ASSERT_OK(err, "test_queue_stack_nested_map__attach"))
+		goto out;
+
+	if (is_map_queue) {
+		prog_fd = bpf_program__fd(skel->progs.test_queue_nesting);
+		err = bpf_prog_test_run_opts(prog_fd, &ropts);
+		ASSERT_OK(err, "test_nested_queue_map_run");
+	} else {
+		prog_fd = bpf_program__fd(skel->progs.test_stack_nesting);
+		err = bpf_prog_test_run_opts(prog_fd, &ropts);
+		ASSERT_OK(err, "test_nested_stack_map_run");
+	}
+
+
+
+out:
+	test_queue_stack_nested_map__destroy(skel);
+}
+
+void test_test_queue_stack_nested_map(void)
+{
+	if (test__start_subtest("map_queue_nesting"))
+		test_map_queue_stack_nesting_success(true);
+	if (test__start_subtest("map_stack_nesting"))
+		test_map_queue_stack_nesting_success(false);
+
+}
+
diff --git a/tools/testing/selftests/bpf/progs/test_queue_stack_nested_map.c b/tools/testing/selftests/bpf/progs/test_queue_stack_nested_map.c
new file mode 100644
index 000000000000..6d22016b1709
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/test_queue_stack_nested_map.c
@@ -0,0 +1,62 @@ 
+// SPDX-License-Identifier: GPL-2.0
+#include "vmlinux.h"
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_tracing.h>
+
+struct {
+	__uint(type, BPF_MAP_TYPE_STACK);
+	__uint(max_entries, 32);
+	__uint(map_flags, 0);
+	__uint(key_size, 0);
+	__uint(value_size, sizeof(__u32));
+} map_stack SEC(".maps");
+
+struct {
+	__uint(type, BPF_MAP_TYPE_QUEUE);
+	__uint(max_entries, 32);
+	__uint(map_flags, 0);
+	__uint(key_size, 0);
+	__uint(value_size, sizeof(__u32));
+} map_queue SEC(".maps");
+
+SEC("fentry/_raw_spin_unlock_irqrestore")
+int BPF_PROG(test_stack_nesting2, raw_spinlock_t *lock, unsigned long flags)
+{
+	__u32 value = 1;
+
+	bpf_map_push_elem(&map_stack, &value, 0);
+
+	return 0;
+}
+
+SEC("fentry/bpf_fentry_test1")
+int BPF_PROG(test_stack_nesting, int a)
+{
+	__u32 value = 1;
+
+	bpf_map_push_elem(&map_stack, &value, 0);
+
+	return 0;
+}
+
+SEC("fentry/_raw_spin_unlock_irqrestore")
+int BPF_PROG(test_queue_nesting2, raw_spinlock_t *lock, unsigned long flags)
+{
+	__u32 value = 1;
+
+	bpf_map_pop_elem(&map_queue, &value);
+
+	return 0;
+}
+
+SEC("fentry/bpf_fentry_test1")
+int BPF_PROG(test_queue_nesting, int a)
+{
+	__u32 value = 1;
+
+	bpf_map_push_elem(&map_queue, &value, 0);
+
+	return 0;
+}
+
+char _license[] SEC("license") = "GPL";