1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (c) 2019 Facebook 3 #include <test_progs.h> 4 static int libbpf_debug_print(enum libbpf_print_level level, 5 const char *format, va_list args) 6 { 7 if (level != LIBBPF_DEBUG) { 8 vprintf(format, args); 9 return 0; 10 } 11 12 if (!strstr(format, "verifier log")) 13 return 0; 14 vprintf("%s", args); 15 return 0; 16 } 17 18 extern int extra_prog_load_log_flags; 19 20 static int check_load(const char *file, enum bpf_prog_type type) 21 { 22 struct bpf_prog_load_attr attr; 23 struct bpf_object *obj = NULL; 24 int err, prog_fd; 25 26 memset(&attr, 0, sizeof(struct bpf_prog_load_attr)); 27 attr.file = file; 28 attr.prog_type = type; 29 attr.log_level = 4 | extra_prog_load_log_flags; 30 attr.prog_flags = BPF_F_TEST_RND_HI32; 31 err = bpf_prog_load_xattr(&attr, &obj, &prog_fd); 32 bpf_object__close(obj); 33 return err; 34 } 35 36 struct scale_test_def { 37 const char *file; 38 enum bpf_prog_type attach_type; 39 bool fails; 40 }; 41 42 static void scale_test(const char *file, 43 enum bpf_prog_type attach_type, 44 bool should_fail) 45 { 46 libbpf_print_fn_t old_print_fn = NULL; 47 int err; 48 49 if (env.verifier_stats) { 50 test__force_log(); 51 old_print_fn = libbpf_set_print(libbpf_debug_print); 52 } 53 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"); 59 60 if (env.verifier_stats) 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); 204 } 205 206 void test_verif_twfw() 207 { 208 scale_test("twfw.o", BPF_PROG_TYPE_CGROUP_SKB, false); 209 } 210