On Tue, 14 May 2024 at 08:23, Siddharth Chintamaneni <sidchintamaneni@xxxxxxxxx> wrote: > > Added selftests to check for nested deadlocks in queue and stack maps. > > test_map_queue_stack_nesting_success:PASS:test_queue_stack_nested_map__open 0 nsec > test_map_queue_stack_nesting_success:PASS:test_queue_stack_nested_map__load 0 nsec > test_map_queue_stack_nesting_success:PASS:test_queue_stack_nested_map__attach 0 nsec > test_map_queue_stack_nesting_success:PASS:MAP Write 0 nsec > test_map_queue_stack_nesting_success:PASS:no map nesting 0 nsec > test_map_queue_stack_nesting_success:PASS:no map nesting 0 nsec > 384/1 test_queue_stack_nested_map/map_queue_nesting:OK > test_map_queue_stack_nesting_success:PASS:test_queue_stack_nested_map__open 0 nsec > test_map_queue_stack_nesting_success:PASS:test_queue_stack_nested_map__load 0 nsec > test_map_queue_stack_nesting_success:PASS:test_queue_stack_nested_map__attach 0 nsec > test_map_queue_stack_nesting_success:PASS:MAP Write 0 nsec > test_map_queue_stack_nesting_success:PASS:no map nesting 0 nsec > 384/2 test_queue_stack_nested_map/map_stack_nesting:OK > 384 test_queue_stack_nested_map:OK > Summary: 1/2 PASSED, 0 SKIPPED, 0 FAILED > > Signed-off-by: Siddharth Chintamaneni <sidchintamaneni@xxxxxxxxx> > --- > samples/bpf/Makefile | 3 + Somehow my test environment file got sneaked in. I will remove this file and send a revised one for selftests. > .../prog_tests/test_queue_stack_nested_map.c | 69 +++++++++++ > .../bpf/progs/test_queue_stack_nested_map.c | 116 ++++++++++++++++++ > 3 files changed, 188 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/samples/bpf/Makefile b/samples/bpf/Makefile > index 9aa027b144df..9e1abf0e21ad 100644 > --- a/samples/bpf/Makefile > +++ b/samples/bpf/Makefile > @@ -7,6 +7,7 @@ pound := \# > > # List of programs to build > tprogs-y := test_lru_dist > +tprogs-y += sid_queue_stack > tprogs-y += sock_example > tprogs-y += fds_example > tprogs-y += sockex1 > @@ -98,6 +99,7 @@ ibumad-objs := ibumad_user.o > hbm-objs := hbm.o $(CGROUP_HELPERS) > > xdp_router_ipv4-objs := xdp_router_ipv4_user.o $(XDP_SAMPLE) > +sid_queue_stack-objs := sid_queue_stack_user.o > > # Tell kbuild to always build the programs > always-y := $(tprogs-y) > @@ -149,6 +151,7 @@ always-y += task_fd_query_kern.o > always-y += ibumad_kern.o > always-y += hbm_out_kern.o > always-y += hbm_edt_kern.o > +always-y += sid_queue_stack_kern.o > > TPROGS_CFLAGS = $(TPROGS_USER_CFLAGS) > TPROGS_LDFLAGS = $(TPROGS_USER_LDFLAGS) > 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..fc46561788af > --- /dev/null > +++ b/tools/testing/selftests/bpf/prog_tests/test_queue_stack_nested_map.c > @@ -0,0 +1,69 @@ > +// 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; > + > + skel = test_queue_stack_nested_map__open(); > + if (!ASSERT_OK_PTR(skel, "test_queue_stack_nested_map__open")) > + return; > + > + err = test_queue_stack_nested_map__load(skel); > + if (!ASSERT_OK(err, "test_queue_stack_nested_map__load")) > + goto out; > + > + skel->bss->pid = getpid(); > + err = test_queue_stack_nested_map__attach(skel); > + if (!ASSERT_OK(err, "test_queue_stack_nested_map__attach")) > + goto out; > + > + /* trigger map from userspace to check nesting */ > + int value = 0; > + > + do { > + if (is_map_queue) { > + err = bpf_map_update_elem(bpf_map__fd(skel->maps.map_queue), > + NULL, &value, 0); > + if (err < 0) > + break; > + err = bpf_map_lookup_and_delete_elem(bpf_map__fd(skel->maps.map_queue), > + NULL, &value); > + } else { > + err = bpf_map_update_elem(bpf_map__fd(skel->maps.map_stack), > + NULL, &value, 0); > + if (err < 0) > + break; > + err = bpf_map_lookup_and_delete_elem(bpf_map__fd(skel->maps.map_stack), > + NULL, &value); > + } > + } while (0); > + > + > + if (!ASSERT_OK(err, "MAP Write")) > + goto out; > + > + if (is_map_queue) { > + ASSERT_EQ(skel->bss->err_queue_push, -EBUSY, "no map nesting"); > + ASSERT_EQ(skel->bss->err_queue_pop, -EBUSY, "no map nesting"); > + } else { > + ASSERT_EQ(skel->bss->err_stack, -EBUSY, "no map nesting"); > + } > +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..893a37593206 > --- /dev/null > +++ b/tools/testing/selftests/bpf/progs/test_queue_stack_nested_map.c > @@ -0,0 +1,116 @@ > +// 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(key_size, 0); > + __uint(value_size, sizeof(__u32)); > +} map_stack SEC(".maps"); > + > +struct { > + __uint(type, BPF_MAP_TYPE_QUEUE); > + __uint(max_entries, 32); > + __uint(key_size, 0); > + __uint(value_size, sizeof(__u32)); > +} map_queue SEC(".maps"); > + > + > +int err_queue_push; > +int err_queue_pop; > +int err_stack; > +int pid; > +__u32 trigger_flag_queue_push; > +__u32 trigger_flag_queue_pop; > +__u32 trigger_flag_stack; > + > +SEC("fentry/queue_stack_map_push_elem") > +int BPF_PROG(test_queue_stack_push_trigger, raw_spinlock_t *lock, unsigned long flags) > +{ > + > + if ((bpf_get_current_pid_tgid() >> 32) != pid) > + return 0; > + > + > + trigger_flag_queue_push = 1; > + > + return 0; > +} > + > +SEC("fentry/queue_map_pop_elem") > +int BPF_PROG(test_queue_pop_trigger, raw_spinlock_t *lock, unsigned long flags) > +{ > + > + if ((bpf_get_current_pid_tgid() >> 32) != pid) > + return 0; > + > + trigger_flag_queue_pop = 1; > + > + return 0; > +} > + > + > +SEC("fentry/stack_map_pop_elem") > +int BPF_PROG(test_stack_pop_trigger, raw_spinlock_t *lock, unsigned long flags) > +{ > + > + if ((bpf_get_current_pid_tgid() >> 32) != pid) > + return 0; > + > + trigger_flag_stack = 1; > + > + return 0; > +} > + > +SEC("fentry/_raw_spin_unlock_irqrestore") > +int BPF_PROG(test_queue_pop_nesting, raw_spinlock_t *lock, unsigned long flags) > +{ > + __u32 val; > + > + if ((bpf_get_current_pid_tgid() >> 32) != pid || trigger_flag_queue_pop != 1) > + return 0; > + > + > + err_queue_pop = bpf_map_pop_elem(&map_queue, &val); > + > + trigger_flag_queue_pop = 0; > + > + return 0; > +} > + > +SEC("fentry/_raw_spin_unlock_irqrestore") > +int BPF_PROG(test_stack_nesting, raw_spinlock_t *lock, unsigned long flags) > +{ > + __u32 val; > + > + if ((bpf_get_current_pid_tgid() >> 32) != pid || trigger_flag_stack != 1) > + return 0; > + > + > + err_stack = bpf_map_pop_elem(&map_stack, &val); > + > + trigger_flag_stack = 0; > + > + return 0; > +} > + > + > +SEC("fentry/_raw_spin_unlock_irqrestore") > +int BPF_PROG(test_queue_push_nesting, raw_spinlock_t *lock, unsigned long flags) > +{ > + __u32 val = 1; > + > + if ((bpf_get_current_pid_tgid() >> 32) != pid || trigger_flag_queue_push != 1) { > + return 0; > + } > + > + err_queue_push = bpf_map_push_elem(&map_queue, &val, 0); > + > + trigger_flag_queue_push = 0; > + > + return 0; > +} > + > +char _license[] SEC("license") = "GPL"; > -- > 2.44.0 >