Commit 57c8d362 authored by Alexei Starovoitov's avatar Alexei Starovoitov

Merge branch 'Parallelize verif_scale selftests'

Andrii Nakryiko says:

====================

Reduce amount of waiting time when running test_progs in parallel mode (-j) by
splitting bpf_verif_scale selftests into multiple tests. Previously it was
structured as a test with multiple subtests, but subtests are not easily
parallelizable with test_progs' infra. Also in practice each scale subtest is
really an independent test with nothing shared across all substest.

This patch set changes how test_progs test discovery works. Now it is possible
to define multiple tests within a single source code file. One of the patches
also marks tc_redirect selftests as serial, because it's extremely harmful to
the test system when run in parallel mode.
====================
Acked-by: default avatarYucong Sun <sunyucong@gmail.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parents c825f5fe 3762a39c
...@@ -421,10 +421,9 @@ ifeq ($($(TRUNNER_TESTS_DIR)-tests-hdr),) ...@@ -421,10 +421,9 @@ ifeq ($($(TRUNNER_TESTS_DIR)-tests-hdr),)
$(TRUNNER_TESTS_DIR)-tests-hdr := y $(TRUNNER_TESTS_DIR)-tests-hdr := y
$(TRUNNER_TESTS_HDR): $(TRUNNER_TESTS_DIR)/*.c $(TRUNNER_TESTS_HDR): $(TRUNNER_TESTS_DIR)/*.c
$$(call msg,TEST-HDR,$(TRUNNER_BINARY),$$@) $$(call msg,TEST-HDR,$(TRUNNER_BINARY),$$@)
$$(shell ( cd $(TRUNNER_TESTS_DIR); \ $$(shell (echo '/* Generated header, do not edit */'; \
echo '/* Generated header, do not edit */'; \ sed -n -E 's/^void (serial_)?test_([a-zA-Z0-9_]+)\((void)?\).*/DEFINE_TEST(\2)/p' \
ls *.c 2> /dev/null | \ $(TRUNNER_TESTS_DIR)/*.c | sort ; \
sed -e 's@\([^\.]*\)\.c@DEFINE_TEST(\1)@'; \
) > $$@) ) > $$@)
endif endif
......
...@@ -39,82 +39,166 @@ struct scale_test_def { ...@@ -39,82 +39,166 @@ struct scale_test_def {
bool fails; bool fails;
}; };
void test_bpf_verif_scale(void) static void scale_test(const char *file,
enum bpf_prog_type attach_type,
bool should_fail)
{ {
struct scale_test_def tests[] = { libbpf_print_fn_t old_print_fn = NULL;
{ "loop3.o", BPF_PROG_TYPE_RAW_TRACEPOINT, true /* fails */ }, int err;
if (env.verifier_stats) {
test__force_log();
old_print_fn = libbpf_set_print(libbpf_debug_print);
}
err = check_load(file, attach_type);
if (should_fail)
ASSERT_ERR(err, "expect_error");
else
ASSERT_OK(err, "expect_success");
if (env.verifier_stats)
libbpf_set_print(old_print_fn);
}
void test_verif_scale1()
{
scale_test("test_verif_scale1.o", BPF_PROG_TYPE_SCHED_CLS, false);
}
void test_verif_scale2()
{
scale_test("test_verif_scale2.o", BPF_PROG_TYPE_SCHED_CLS, false);
}
void test_verif_scale3()
{
scale_test("test_verif_scale3.o", BPF_PROG_TYPE_SCHED_CLS, false);
}
void test_verif_scale_pyperf_global()
{
scale_test("pyperf_global.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false);
}
{ "test_verif_scale1.o", BPF_PROG_TYPE_SCHED_CLS }, void test_verif_scale_pyperf_subprogs()
{ "test_verif_scale2.o", BPF_PROG_TYPE_SCHED_CLS }, {
{ "test_verif_scale3.o", BPF_PROG_TYPE_SCHED_CLS }, scale_test("pyperf_subprogs.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false);
}
{ "pyperf_global.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, void test_verif_scale_pyperf50()
{ "pyperf_subprogs.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, {
/* full unroll by llvm */
scale_test("pyperf50.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false);
}
void test_verif_scale_pyperf100()
{
/* full unroll by llvm */ /* full unroll by llvm */
{ "pyperf50.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, scale_test("pyperf100.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false);
{ "pyperf100.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, }
{ "pyperf180.o", BPF_PROG_TYPE_RAW_TRACEPOINT },
void test_verif_scale_pyperf180()
{
/* full unroll by llvm */
scale_test("pyperf180.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false);
}
void test_verif_scale_pyperf600()
{
/* partial unroll. llvm will unroll loop ~150 times. /* partial unroll. llvm will unroll loop ~150 times.
* C loop count -> 600. * C loop count -> 600.
* Asm loop count -> 4. * Asm loop count -> 4.
* 16k insns in loop body. * 16k insns in loop body.
* Total of 5 such loops. Total program size ~82k insns. * Total of 5 such loops. Total program size ~82k insns.
*/ */
{ "pyperf600.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, scale_test("pyperf600.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false);
}
void test_verif_scale_pyperf600_nounroll()
{
/* no unroll at all. /* no unroll at all.
* C loop count -> 600. * C loop count -> 600.
* ASM loop count -> 600. * ASM loop count -> 600.
* ~110 insns in loop body. * ~110 insns in loop body.
* Total of 5 such loops. Total program size ~1500 insns. * Total of 5 such loops. Total program size ~1500 insns.
*/ */
{ "pyperf600_nounroll.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, scale_test("pyperf600_nounroll.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false);
}
{ "loop1.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, void test_verif_scale_loop1()
{ "loop2.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, {
{ "loop4.o", BPF_PROG_TYPE_SCHED_CLS }, scale_test("loop1.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false);
{ "loop5.o", BPF_PROG_TYPE_SCHED_CLS }, }
{ "loop6.o", BPF_PROG_TYPE_KPROBE },
void test_verif_scale_loop2()
{
scale_test("loop2.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false);
}
void test_verif_scale_loop3_fail()
{
scale_test("loop3.o", BPF_PROG_TYPE_RAW_TRACEPOINT, true /* fails */);
}
void test_verif_scale_loop4()
{
scale_test("loop4.o", BPF_PROG_TYPE_SCHED_CLS, false);
}
void test_verif_scale_loop5()
{
scale_test("loop5.o", BPF_PROG_TYPE_SCHED_CLS, false);
}
void test_verif_scale_loop6()
{
scale_test("loop6.o", BPF_PROG_TYPE_KPROBE, false);
}
void test_verif_scale_strobemeta()
{
/* partial unroll. 19k insn in a loop. /* partial unroll. 19k insn in a loop.
* Total program size 20.8k insn. * Total program size 20.8k insn.
* ~350k processed_insns * ~350k processed_insns
*/ */
{ "strobemeta.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, scale_test("strobemeta.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false);
}
void test_verif_scale_strobemeta_nounroll1()
{
/* no unroll, tiny loops */ /* no unroll, tiny loops */
{ "strobemeta_nounroll1.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, scale_test("strobemeta_nounroll1.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false);
{ "strobemeta_nounroll2.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, }
/* non-inlined subprogs */
{ "strobemeta_subprogs.o", BPF_PROG_TYPE_RAW_TRACEPOINT },
{ "test_sysctl_loop1.o", BPF_PROG_TYPE_CGROUP_SYSCTL },
{ "test_sysctl_loop2.o", BPF_PROG_TYPE_CGROUP_SYSCTL },
{ "test_xdp_loop.o", BPF_PROG_TYPE_XDP }, void test_verif_scale_strobemeta_nounroll2()
{ "test_seg6_loop.o", BPF_PROG_TYPE_LWT_SEG6LOCAL }, {
}; /* no unroll, tiny loops */
libbpf_print_fn_t old_print_fn = NULL; scale_test("strobemeta_nounroll2.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false);
int err, i; }
if (env.verifier_stats) { void test_verif_scale_strobemeta_subprogs()
test__force_log(); {
old_print_fn = libbpf_set_print(libbpf_debug_print); /* non-inlined subprogs */
} scale_test("strobemeta_subprogs.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false);
}
for (i = 0; i < ARRAY_SIZE(tests); i++) { void test_verif_scale_sysctl_loop1()
const struct scale_test_def *test = &tests[i]; {
scale_test("test_sysctl_loop1.o", BPF_PROG_TYPE_CGROUP_SYSCTL, false);
}
if (!test__start_subtest(test->file)) void test_verif_scale_sysctl_loop2()
continue; {
scale_test("test_sysctl_loop2.o", BPF_PROG_TYPE_CGROUP_SYSCTL, false);
}
err = check_load(test->file, test->attach_type); void test_verif_scale_xdp_loop()
CHECK_FAIL(err && !test->fails); {
} scale_test("test_xdp_loop.o", BPF_PROG_TYPE_XDP, false);
}
if (env.verifier_stats) void test_verif_scale_seg6_loop()
libbpf_set_print(old_print_fn); {
scale_test("test_seg6_loop.o", BPF_PROG_TYPE_LWT_SEG6LOCAL, false);
} }
...@@ -133,7 +133,7 @@ static char *dump_buf; ...@@ -133,7 +133,7 @@ static char *dump_buf;
static size_t dump_buf_sz; static size_t dump_buf_sz;
static FILE *dump_buf_file; static FILE *dump_buf_file;
void test_btf_dump_incremental(void) static void test_btf_dump_incremental(void)
{ {
struct btf *btf = NULL; struct btf *btf = NULL;
struct btf_dump *d = NULL; struct btf_dump *d = NULL;
......
...@@ -117,14 +117,14 @@ static int resolve_symbols(void) ...@@ -117,14 +117,14 @@ static int resolve_symbols(void)
return 0; return 0;
} }
int test_resolve_btfids(void) void test_resolve_btfids(void)
{ {
__u32 *test_list, *test_lists[] = { test_list_local, test_list_global }; __u32 *test_list, *test_lists[] = { test_list_local, test_list_global };
unsigned int i, j; unsigned int i, j;
int ret = 0; int ret = 0;
if (resolve_symbols()) if (resolve_symbols())
return -1; return;
/* Check BTF_ID_LIST(test_list_local) and /* Check BTF_ID_LIST(test_list_local) and
* BTF_ID_LIST_GLOBAL(test_list_global) IDs * BTF_ID_LIST_GLOBAL(test_list_global) IDs
...@@ -138,7 +138,7 @@ int test_resolve_btfids(void) ...@@ -138,7 +138,7 @@ int test_resolve_btfids(void)
test_symbols[i].name, test_symbols[i].name,
test_list[i], test_symbols[i].id); test_list[i], test_symbols[i].id);
if (ret) if (ret)
return ret; return;
} }
} }
...@@ -161,9 +161,7 @@ int test_resolve_btfids(void) ...@@ -161,9 +161,7 @@ int test_resolve_btfids(void)
if (i > 0) { if (i > 0) {
if (!ASSERT_LE(test_set.ids[i - 1], test_set.ids[i], "sort_check")) if (!ASSERT_LE(test_set.ids[i - 1], test_set.ids[i], "sort_check"))
return -1; return;
} }
} }
return ret;
} }
...@@ -42,7 +42,7 @@ static void test_signal_pending_by_type(enum bpf_prog_type prog_type) ...@@ -42,7 +42,7 @@ static void test_signal_pending_by_type(enum bpf_prog_type prog_type)
signal(SIGALRM, SIG_DFL); signal(SIGALRM, SIG_DFL);
} }
void test_signal_pending(enum bpf_prog_type prog_type) void test_signal_pending(void)
{ {
test_signal_pending_by_type(BPF_PROG_TYPE_SOCKET_FILTER); test_signal_pending_by_type(BPF_PROG_TYPE_SOCKET_FILTER);
test_signal_pending_by_type(BPF_PROG_TYPE_FLOW_DISSECTOR); test_signal_pending_by_type(BPF_PROG_TYPE_FLOW_DISSECTOR);
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
#define EXP_NO_BUF_RET 29 #define EXP_NO_BUF_RET 29
void test_snprintf_positive(void) static void test_snprintf_positive(void)
{ {
char exp_addr_out[] = EXP_ADDR_OUT; char exp_addr_out[] = EXP_ADDR_OUT;
char exp_sym_out[] = EXP_SYM_OUT; char exp_sym_out[] = EXP_SYM_OUT;
...@@ -103,7 +103,7 @@ static int load_single_snprintf(char *fmt) ...@@ -103,7 +103,7 @@ static int load_single_snprintf(char *fmt)
return ret; return ret;
} }
void test_snprintf_negative(void) static void test_snprintf_negative(void)
{ {
ASSERT_OK(load_single_snprintf("valid %d"), "valid usage"); ASSERT_OK(load_single_snprintf("valid %d"), "valid usage");
......
...@@ -769,7 +769,7 @@ static void *test_tc_redirect_run_tests(void *arg) ...@@ -769,7 +769,7 @@ static void *test_tc_redirect_run_tests(void *arg)
return NULL; return NULL;
} }
void test_tc_redirect(void) void serial_test_tc_redirect(void)
{ {
pthread_t test_thread; pthread_t test_thread;
int err; int err;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#include <test_progs.h> #include <test_progs.h>
#include <network_helpers.h> #include <network_helpers.h>
void test_xdp_adjust_tail_shrink(void) static void test_xdp_adjust_tail_shrink(void)
{ {
const char *file = "./test_xdp_adjust_tail_shrink.o"; const char *file = "./test_xdp_adjust_tail_shrink.o";
__u32 duration, retval, size, expect_sz; __u32 duration, retval, size, expect_sz;
...@@ -30,7 +30,7 @@ void test_xdp_adjust_tail_shrink(void) ...@@ -30,7 +30,7 @@ void test_xdp_adjust_tail_shrink(void)
bpf_object__close(obj); bpf_object__close(obj);
} }
void test_xdp_adjust_tail_grow(void) static void test_xdp_adjust_tail_grow(void)
{ {
const char *file = "./test_xdp_adjust_tail_grow.o"; const char *file = "./test_xdp_adjust_tail_grow.o";
struct bpf_object *obj; struct bpf_object *obj;
...@@ -58,7 +58,7 @@ void test_xdp_adjust_tail_grow(void) ...@@ -58,7 +58,7 @@ void test_xdp_adjust_tail_grow(void)
bpf_object__close(obj); bpf_object__close(obj);
} }
void test_xdp_adjust_tail_grow2(void) static void test_xdp_adjust_tail_grow2(void)
{ {
const char *file = "./test_xdp_adjust_tail_grow.o"; const char *file = "./test_xdp_adjust_tail_grow.o";
char buf[4096]; /* avoid segfault: large buf to hold grow results */ char buf[4096]; /* avoid segfault: large buf to hold grow results */
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#define IFINDEX_LO 1 #define IFINDEX_LO 1
void test_xdp_with_devmap_helpers(void) static void test_xdp_with_devmap_helpers(void)
{ {
struct test_xdp_with_devmap_helpers *skel; struct test_xdp_with_devmap_helpers *skel;
struct bpf_prog_info info = {}; struct bpf_prog_info info = {};
...@@ -60,7 +60,7 @@ void test_xdp_with_devmap_helpers(void) ...@@ -60,7 +60,7 @@ void test_xdp_with_devmap_helpers(void)
test_xdp_with_devmap_helpers__destroy(skel); test_xdp_with_devmap_helpers__destroy(skel);
} }
void test_neg_xdp_devmap_helpers(void) static void test_neg_xdp_devmap_helpers(void)
{ {
struct test_xdp_devmap_helpers *skel; struct test_xdp_devmap_helpers *skel;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment