Loading tools/testing/selftests/bpf/bpf_experimental.h +1 −0 Original line number Diff line number Diff line Loading @@ -470,4 +470,5 @@ extern int bpf_iter_css_new(struct bpf_iter_css *it, extern struct cgroup_subsys_state *bpf_iter_css_next(struct bpf_iter_css *it) __weak __ksym; extern void bpf_iter_css_destroy(struct bpf_iter_css *it) __weak __ksym; extern int bpf_wq_init(struct bpf_wq *wq, void *p__map, unsigned int flags) __weak __ksym; #endif tools/testing/selftests/bpf/prog_tests/wq.c +8 −0 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ /* Copyright (c) 2024 Benjamin Tissoires */ #include <test_progs.h> #include "wq.skel.h" #include "wq_failures.skel.h" void serial_test_wq(void) { Loading @@ -9,3 +10,10 @@ void serial_test_wq(void) RUN_TESTS(wq); } void serial_test_failures_wq(void) { LIBBPF_OPTS(bpf_test_run_opts, topts); RUN_TESTS(wq_failures); } tools/testing/selftests/bpf/progs/wq.c +10 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ struct { static int test_elem_callback(void *map, int *key) { struct elem init = {}, *val; struct bpf_wq *wq; if (map == &lru && bpf_map_update_elem(map, key, &init, 0)) Loading @@ -61,12 +62,17 @@ static int test_elem_callback(void *map, int *key) if (!val) return -2; wq = &val->w; if (bpf_wq_init(wq, map, 0) != 0) return -3; return 0; } static int test_hmap_elem_callback(void *map, int *key) { struct hmap_elem init = {}, *val; struct bpf_wq *wq; if (bpf_map_update_elem(map, key, &init, 0)) return -1; Loading @@ -75,6 +81,10 @@ static int test_hmap_elem_callback(void *map, int *key) if (!val) return -2; wq = &val->work; if (bpf_wq_init(wq, map, 0) != 0) return -3; return 0; } Loading tools/testing/selftests/bpf/progs/wq_failures.c 0 → 100644 +78 −0 Original line number Diff line number Diff line // 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 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"); SEC("tc") /* test that bpf_wq_init takes a map as a second argument */ __log_level(2) __flag(BPF_F_TEST_STATE_FREQ) __failure __msg(": (85) call bpf_wq_init#") /* anchor message */ __msg("pointer in R2 isn't map pointer") long test_wq_init_nomap(void *ctx) { struct bpf_wq *wq; struct elem *val; int key = 0; val = bpf_map_lookup_elem(&array, &key); if (!val) return -1; wq = &val->w; if (bpf_wq_init(wq, &key, 0) != 0) return -3; return 0; } SEC("tc") /* test that the workqueue is part of the map in bpf_wq_init */ __log_level(2) __flag(BPF_F_TEST_STATE_FREQ) __failure __msg(": (85) call bpf_wq_init#") /* anchor message */ __msg("workqueue pointer in R1 map_uid=0 doesn't match map pointer in R2 map_uid=0") long test_wq_init_wrong_map(void *ctx) { struct bpf_wq *wq; struct elem *val; int key = 0; val = bpf_map_lookup_elem(&array, &key); if (!val) return -1; wq = &val->w; if (bpf_wq_init(wq, &lru, 0) != 0) return -3; return 0; } Loading
tools/testing/selftests/bpf/bpf_experimental.h +1 −0 Original line number Diff line number Diff line Loading @@ -470,4 +470,5 @@ extern int bpf_iter_css_new(struct bpf_iter_css *it, extern struct cgroup_subsys_state *bpf_iter_css_next(struct bpf_iter_css *it) __weak __ksym; extern void bpf_iter_css_destroy(struct bpf_iter_css *it) __weak __ksym; extern int bpf_wq_init(struct bpf_wq *wq, void *p__map, unsigned int flags) __weak __ksym; #endif
tools/testing/selftests/bpf/prog_tests/wq.c +8 −0 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ /* Copyright (c) 2024 Benjamin Tissoires */ #include <test_progs.h> #include "wq.skel.h" #include "wq_failures.skel.h" void serial_test_wq(void) { Loading @@ -9,3 +10,10 @@ void serial_test_wq(void) RUN_TESTS(wq); } void serial_test_failures_wq(void) { LIBBPF_OPTS(bpf_test_run_opts, topts); RUN_TESTS(wq_failures); }
tools/testing/selftests/bpf/progs/wq.c +10 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ struct { static int test_elem_callback(void *map, int *key) { struct elem init = {}, *val; struct bpf_wq *wq; if (map == &lru && bpf_map_update_elem(map, key, &init, 0)) Loading @@ -61,12 +62,17 @@ static int test_elem_callback(void *map, int *key) if (!val) return -2; wq = &val->w; if (bpf_wq_init(wq, map, 0) != 0) return -3; return 0; } static int test_hmap_elem_callback(void *map, int *key) { struct hmap_elem init = {}, *val; struct bpf_wq *wq; if (bpf_map_update_elem(map, key, &init, 0)) return -1; Loading @@ -75,6 +81,10 @@ static int test_hmap_elem_callback(void *map, int *key) if (!val) return -2; wq = &val->work; if (bpf_wq_init(wq, map, 0) != 0) return -3; return 0; } Loading
tools/testing/selftests/bpf/progs/wq_failures.c 0 → 100644 +78 −0 Original line number Diff line number Diff line // 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 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"); SEC("tc") /* test that bpf_wq_init takes a map as a second argument */ __log_level(2) __flag(BPF_F_TEST_STATE_FREQ) __failure __msg(": (85) call bpf_wq_init#") /* anchor message */ __msg("pointer in R2 isn't map pointer") long test_wq_init_nomap(void *ctx) { struct bpf_wq *wq; struct elem *val; int key = 0; val = bpf_map_lookup_elem(&array, &key); if (!val) return -1; wq = &val->w; if (bpf_wq_init(wq, &key, 0) != 0) return -3; return 0; } SEC("tc") /* test that the workqueue is part of the map in bpf_wq_init */ __log_level(2) __flag(BPF_F_TEST_STATE_FREQ) __failure __msg(": (85) call bpf_wq_init#") /* anchor message */ __msg("workqueue pointer in R1 map_uid=0 doesn't match map pointer in R2 map_uid=0") long test_wq_init_wrong_map(void *ctx) { struct bpf_wq *wq; struct elem *val; int key = 0; val = bpf_map_lookup_elem(&array, &key); if (!val) return -1; wq = &val->w; if (bpf_wq_init(wq, &lru, 0) != 0) return -3; return 0; }