Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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: Yucong Sun <sunyucong@gmail.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

+168 -87
+3 -4
tools/testing/selftests/bpf/Makefile
··· 421 421 $(TRUNNER_TESTS_DIR)-tests-hdr := y 422 422 $(TRUNNER_TESTS_HDR): $(TRUNNER_TESTS_DIR)/*.c 423 423 $$(call msg,TEST-HDR,$(TRUNNER_BINARY),$$@) 424 - $$(shell ( cd $(TRUNNER_TESTS_DIR); \ 425 - echo '/* Generated header, do not edit */'; \ 426 - ls *.c 2> /dev/null | \ 427 - sed -e 's@\([^\.]*\)\.c@DEFINE_TEST(\1)@'; \ 424 + $$(shell (echo '/* Generated header, do not edit */'; \ 425 + sed -n -E 's/^void (serial_)?test_([a-zA-Z0-9_]+)\((void)?\).*/DEFINE_TEST(\2)/p' \ 426 + $(TRUNNER_TESTS_DIR)/*.c | sort ; \ 428 427 ) > $$@) 429 428 endif 430 429
+151 -67
tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c
··· 39 39 bool fails; 40 40 }; 41 41 42 - void test_bpf_verif_scale(void) 42 + static void scale_test(const char *file, 43 + enum bpf_prog_type attach_type, 44 + bool should_fail) 43 45 { 44 - struct scale_test_def tests[] = { 45 - { "loop3.o", BPF_PROG_TYPE_RAW_TRACEPOINT, true /* fails */ }, 46 - 47 - { "test_verif_scale1.o", BPF_PROG_TYPE_SCHED_CLS }, 48 - { "test_verif_scale2.o", BPF_PROG_TYPE_SCHED_CLS }, 49 - { "test_verif_scale3.o", BPF_PROG_TYPE_SCHED_CLS }, 50 - 51 - { "pyperf_global.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, 52 - { "pyperf_subprogs.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, 53 - 54 - /* full unroll by llvm */ 55 - { "pyperf50.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, 56 - { "pyperf100.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, 57 - { "pyperf180.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, 58 - 59 - /* partial unroll. llvm will unroll loop ~150 times. 60 - * C loop count -> 600. 61 - * Asm loop count -> 4. 62 - * 16k insns in loop body. 63 - * Total of 5 such loops. Total program size ~82k insns. 64 - */ 65 - { "pyperf600.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, 66 - 67 - /* no unroll at all. 68 - * C loop count -> 600. 69 - * ASM loop count -> 600. 70 - * ~110 insns in loop body. 71 - * Total of 5 such loops. Total program size ~1500 insns. 72 - */ 73 - { "pyperf600_nounroll.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, 74 - 75 - { "loop1.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, 76 - { "loop2.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, 77 - { "loop4.o", BPF_PROG_TYPE_SCHED_CLS }, 78 - { "loop5.o", BPF_PROG_TYPE_SCHED_CLS }, 79 - { "loop6.o", BPF_PROG_TYPE_KPROBE }, 80 - 81 - /* partial unroll. 19k insn in a loop. 82 - * Total program size 20.8k insn. 83 - * ~350k processed_insns 84 - */ 85 - { "strobemeta.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, 86 - 87 - /* no unroll, tiny loops */ 88 - { "strobemeta_nounroll1.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, 89 - { "strobemeta_nounroll2.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, 90 - 91 - /* non-inlined subprogs */ 92 - { "strobemeta_subprogs.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, 93 - 94 - { "test_sysctl_loop1.o", BPF_PROG_TYPE_CGROUP_SYSCTL }, 95 - { "test_sysctl_loop2.o", BPF_PROG_TYPE_CGROUP_SYSCTL }, 96 - 97 - { "test_xdp_loop.o", BPF_PROG_TYPE_XDP }, 98 - { "test_seg6_loop.o", BPF_PROG_TYPE_LWT_SEG6LOCAL }, 99 - }; 100 46 libbpf_print_fn_t old_print_fn = NULL; 101 - int err, i; 47 + int err; 102 48 103 49 if (env.verifier_stats) { 104 50 test__force_log(); 105 51 old_print_fn = libbpf_set_print(libbpf_debug_print); 106 52 } 107 53 108 - for (i = 0; i < ARRAY_SIZE(tests); i++) { 109 - const struct scale_test_def *test = &tests[i]; 110 - 111 - if (!test__start_subtest(test->file)) 112 - continue; 113 - 114 - err = check_load(test->file, test->attach_type); 115 - CHECK_FAIL(err && !test->fails); 116 - } 54 + err = check_load(file, attach_type); 55 + if (should_fail) 56 + ASSERT_ERR(err, "expect_error"); 57 + else 58 + ASSERT_OK(err, "expect_success"); 117 59 118 60 if (env.verifier_stats) 119 61 libbpf_set_print(old_print_fn); 62 + } 63 + 64 + void test_verif_scale1() 65 + { 66 + scale_test("test_verif_scale1.o", BPF_PROG_TYPE_SCHED_CLS, false); 67 + } 68 + 69 + void test_verif_scale2() 70 + { 71 + scale_test("test_verif_scale2.o", BPF_PROG_TYPE_SCHED_CLS, false); 72 + } 73 + 74 + void test_verif_scale3() 75 + { 76 + scale_test("test_verif_scale3.o", BPF_PROG_TYPE_SCHED_CLS, false); 77 + } 78 + 79 + void test_verif_scale_pyperf_global() 80 + { 81 + scale_test("pyperf_global.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false); 82 + } 83 + 84 + void test_verif_scale_pyperf_subprogs() 85 + { 86 + scale_test("pyperf_subprogs.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false); 87 + } 88 + 89 + void test_verif_scale_pyperf50() 90 + { 91 + /* full unroll by llvm */ 92 + scale_test("pyperf50.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false); 93 + } 94 + 95 + void test_verif_scale_pyperf100() 96 + { 97 + /* full unroll by llvm */ 98 + scale_test("pyperf100.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false); 99 + } 100 + 101 + void test_verif_scale_pyperf180() 102 + { 103 + /* full unroll by llvm */ 104 + scale_test("pyperf180.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false); 105 + } 106 + 107 + void test_verif_scale_pyperf600() 108 + { 109 + /* partial unroll. llvm will unroll loop ~150 times. 110 + * C loop count -> 600. 111 + * Asm loop count -> 4. 112 + * 16k insns in loop body. 113 + * Total of 5 such loops. Total program size ~82k insns. 114 + */ 115 + scale_test("pyperf600.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false); 116 + } 117 + 118 + void test_verif_scale_pyperf600_nounroll() 119 + { 120 + /* no unroll at all. 121 + * C loop count -> 600. 122 + * ASM loop count -> 600. 123 + * ~110 insns in loop body. 124 + * Total of 5 such loops. Total program size ~1500 insns. 125 + */ 126 + scale_test("pyperf600_nounroll.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false); 127 + } 128 + 129 + void test_verif_scale_loop1() 130 + { 131 + scale_test("loop1.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false); 132 + } 133 + 134 + void test_verif_scale_loop2() 135 + { 136 + scale_test("loop2.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false); 137 + } 138 + 139 + void test_verif_scale_loop3_fail() 140 + { 141 + scale_test("loop3.o", BPF_PROG_TYPE_RAW_TRACEPOINT, true /* fails */); 142 + } 143 + 144 + void test_verif_scale_loop4() 145 + { 146 + scale_test("loop4.o", BPF_PROG_TYPE_SCHED_CLS, false); 147 + } 148 + 149 + void test_verif_scale_loop5() 150 + { 151 + scale_test("loop5.o", BPF_PROG_TYPE_SCHED_CLS, false); 152 + } 153 + 154 + void test_verif_scale_loop6() 155 + { 156 + scale_test("loop6.o", BPF_PROG_TYPE_KPROBE, false); 157 + } 158 + 159 + void test_verif_scale_strobemeta() 160 + { 161 + /* partial unroll. 19k insn in a loop. 162 + * Total program size 20.8k insn. 163 + * ~350k processed_insns 164 + */ 165 + scale_test("strobemeta.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false); 166 + } 167 + 168 + void test_verif_scale_strobemeta_nounroll1() 169 + { 170 + /* no unroll, tiny loops */ 171 + scale_test("strobemeta_nounroll1.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false); 172 + } 173 + 174 + void test_verif_scale_strobemeta_nounroll2() 175 + { 176 + /* no unroll, tiny loops */ 177 + scale_test("strobemeta_nounroll2.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false); 178 + } 179 + 180 + void test_verif_scale_strobemeta_subprogs() 181 + { 182 + /* non-inlined subprogs */ 183 + scale_test("strobemeta_subprogs.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false); 184 + } 185 + 186 + void test_verif_scale_sysctl_loop1() 187 + { 188 + scale_test("test_sysctl_loop1.o", BPF_PROG_TYPE_CGROUP_SYSCTL, false); 189 + } 190 + 191 + void test_verif_scale_sysctl_loop2() 192 + { 193 + scale_test("test_sysctl_loop2.o", BPF_PROG_TYPE_CGROUP_SYSCTL, false); 194 + } 195 + 196 + void test_verif_scale_xdp_loop() 197 + { 198 + scale_test("test_xdp_loop.o", BPF_PROG_TYPE_XDP, false); 199 + } 200 + 201 + void test_verif_scale_seg6_loop() 202 + { 203 + scale_test("test_seg6_loop.o", BPF_PROG_TYPE_LWT_SEG6LOCAL, false); 120 204 }
+1 -1
tools/testing/selftests/bpf/prog_tests/btf_dump.c
··· 133 133 static size_t dump_buf_sz; 134 134 static FILE *dump_buf_file; 135 135 136 - void test_btf_dump_incremental(void) 136 + static void test_btf_dump_incremental(void) 137 137 { 138 138 struct btf *btf = NULL; 139 139 struct btf_dump *d = NULL;
+4 -6
tools/testing/selftests/bpf/prog_tests/resolve_btfids.c
··· 117 117 return 0; 118 118 } 119 119 120 - int test_resolve_btfids(void) 120 + void test_resolve_btfids(void) 121 121 { 122 122 __u32 *test_list, *test_lists[] = { test_list_local, test_list_global }; 123 123 unsigned int i, j; 124 124 int ret = 0; 125 125 126 126 if (resolve_symbols()) 127 - return -1; 127 + return; 128 128 129 129 /* Check BTF_ID_LIST(test_list_local) and 130 130 * BTF_ID_LIST_GLOBAL(test_list_global) IDs ··· 138 138 test_symbols[i].name, 139 139 test_list[i], test_symbols[i].id); 140 140 if (ret) 141 - return ret; 141 + return; 142 142 } 143 143 } 144 144 ··· 161 161 162 162 if (i > 0) { 163 163 if (!ASSERT_LE(test_set.ids[i - 1], test_set.ids[i], "sort_check")) 164 - return -1; 164 + return; 165 165 } 166 166 } 167 - 168 - return ret; 169 167 }
+1 -1
tools/testing/selftests/bpf/prog_tests/signal_pending.c
··· 42 42 signal(SIGALRM, SIG_DFL); 43 43 } 44 44 45 - void test_signal_pending(enum bpf_prog_type prog_type) 45 + void test_signal_pending(void) 46 46 { 47 47 test_signal_pending_by_type(BPF_PROG_TYPE_SOCKET_FILTER); 48 48 test_signal_pending_by_type(BPF_PROG_TYPE_FLOW_DISSECTOR);
+2 -2
tools/testing/selftests/bpf/prog_tests/snprintf.c
··· 33 33 34 34 #define EXP_NO_BUF_RET 29 35 35 36 - void test_snprintf_positive(void) 36 + static void test_snprintf_positive(void) 37 37 { 38 38 char exp_addr_out[] = EXP_ADDR_OUT; 39 39 char exp_sym_out[] = EXP_SYM_OUT; ··· 103 103 return ret; 104 104 } 105 105 106 - void test_snprintf_negative(void) 106 + static void test_snprintf_negative(void) 107 107 { 108 108 ASSERT_OK(load_single_snprintf("valid %d"), "valid usage"); 109 109
+1 -1
tools/testing/selftests/bpf/prog_tests/tc_redirect.c
··· 769 769 return NULL; 770 770 } 771 771 772 - void test_tc_redirect(void) 772 + void serial_test_tc_redirect(void) 773 773 { 774 774 pthread_t test_thread; 775 775 int err;
+3 -3
tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c
··· 2 2 #include <test_progs.h> 3 3 #include <network_helpers.h> 4 4 5 - void test_xdp_adjust_tail_shrink(void) 5 + static void test_xdp_adjust_tail_shrink(void) 6 6 { 7 7 const char *file = "./test_xdp_adjust_tail_shrink.o"; 8 8 __u32 duration, retval, size, expect_sz; ··· 30 30 bpf_object__close(obj); 31 31 } 32 32 33 - void test_xdp_adjust_tail_grow(void) 33 + static void test_xdp_adjust_tail_grow(void) 34 34 { 35 35 const char *file = "./test_xdp_adjust_tail_grow.o"; 36 36 struct bpf_object *obj; ··· 58 58 bpf_object__close(obj); 59 59 } 60 60 61 - void test_xdp_adjust_tail_grow2(void) 61 + static void test_xdp_adjust_tail_grow2(void) 62 62 { 63 63 const char *file = "./test_xdp_adjust_tail_grow.o"; 64 64 char buf[4096]; /* avoid segfault: large buf to hold grow results */
+2 -2
tools/testing/selftests/bpf/prog_tests/xdp_devmap_attach.c
··· 8 8 9 9 #define IFINDEX_LO 1 10 10 11 - void test_xdp_with_devmap_helpers(void) 11 + static void test_xdp_with_devmap_helpers(void) 12 12 { 13 13 struct test_xdp_with_devmap_helpers *skel; 14 14 struct bpf_prog_info info = {}; ··· 60 60 test_xdp_with_devmap_helpers__destroy(skel); 61 61 } 62 62 63 - void test_neg_xdp_devmap_helpers(void) 63 + static void test_neg_xdp_devmap_helpers(void) 64 64 { 65 65 struct test_xdp_devmap_helpers *skel; 66 66