Basic tests, will develop in further iterations. Signed-off-by: Delyan Kratunov <delyank@xxxxxx> --- .../selftests/bpf/prog_tests/delayed_work.c | 29 +++++++++ .../selftests/bpf/progs/delayed_irqwork.c | 59 +++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 tools/testing/selftests/bpf/prog_tests/delayed_work.c create mode 100644 tools/testing/selftests/bpf/progs/delayed_irqwork.c diff --git a/tools/testing/selftests/bpf/prog_tests/delayed_work.c b/tools/testing/selftests/bpf/prog_tests/delayed_work.c new file mode 100644 index 000000000000..80ed52c8f34c --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/delayed_work.c @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) Meta Platforms, Inc. and affiliates. */ + +#include <test_progs.h> +#include "delayed_irqwork.skel.h" + +void test_delayed_work(void) +{ + int err; + struct delayed_irqwork *skel; + + skel = delayed_irqwork__open(); + if (!ASSERT_OK_PTR(skel, "skel_open")) + return; + + err = delayed_irqwork__load(skel); + if (!ASSERT_OK(err, "skel_load")) + goto cleanup; + + err = delayed_irqwork__attach(skel); + if (!ASSERT_OK(err, "skel_attach")) + goto cleanup; + + /* trigger tracepoint */ + usleep(1000000); + +cleanup: + delayed_irqwork__destroy(skel); +} diff --git a/tools/testing/selftests/bpf/progs/delayed_irqwork.c b/tools/testing/selftests/bpf/progs/delayed_irqwork.c new file mode 100644 index 000000000000..9fde66616681 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/delayed_irqwork.c @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */ +#include "vmlinux.h" + +#include "bpf_misc.h" +#include <bpf/bpf_helpers.h> +#include <bpf/bpf_tracing.h> +#include <bpf/bpf_core_read.h> + +char _license[] SEC("license") = "GPL"; + +struct map_value_type { + struct bpf_delayed_work work; + struct { + __u32 arg1; + } data; +}; + +struct { + __uint(type, BPF_MAP_TYPE_ARRAY); + __uint(max_entries, 2); + __type(key, __u32); + __type(value, struct map_value_type); +} map1 SEC(".maps"); + +static __noinline int callback(void *args) +{ + struct map_value_type *val = args; + + bpf_printk("callback: %p, %x", val, val->data.arg1); + return 0; +} + +SEC("fentry/" SYS_PREFIX "sys_nanosleep") +int delayed_irqwork(void *ctx) +{ + int ret; + __u32 key = 0; + struct map_value_type *value = (struct map_value_type *) bpf_map_lookup_elem(&map1, &key); + + if (!value) { + bpf_printk("Could not get map value"); + return 0; + } + + value->data.arg1 = 0xcafe; + ret = bpf_delayed_work_submit(&value->work, callback, value, BPF_DELAYED_WORK_IRQWORK); + + key = 1; + value = (struct map_value_type *) bpf_map_lookup_elem(&map1, &key); + if (!value) { + bpf_printk("Could not get map value"); + return 0; + } + value->data.arg1 = 0xbeef; + ret = bpf_delayed_work_submit(&value->work, callback, value, BPF_DELAYED_WORK_IRQWORK); + + return 0; +} -- 2.36.1