1e5e7a8f2SAlexei Starovoitov // SPDX-License-Identifier: GPL-2.0
2e5e7a8f2SAlexei Starovoitov // Copyright (c) 2019 Facebook
3e5e7a8f2SAlexei Starovoitov #include <test_progs.h>
4e5e7a8f2SAlexei Starovoitov static int libbpf_debug_print(enum libbpf_print_level level,
5e5e7a8f2SAlexei Starovoitov 			      const char *format, va_list args)
6e5e7a8f2SAlexei Starovoitov {
70ff97e56SAndrii Nakryiko 	if (level != LIBBPF_DEBUG) {
80ff97e56SAndrii Nakryiko 		test__vprintf(format, args);
90ff97e56SAndrii Nakryiko 		return 0;
100ff97e56SAndrii Nakryiko 	}
11e5e7a8f2SAlexei Starovoitov 
12e5e7a8f2SAlexei Starovoitov 	if (!strstr(format, "verifier log"))
13e5e7a8f2SAlexei Starovoitov 		return 0;
140ff97e56SAndrii Nakryiko 	test__vprintf("%s", args);
150ff97e56SAndrii Nakryiko 	return 0;
16e5e7a8f2SAlexei Starovoitov }
17e5e7a8f2SAlexei Starovoitov 
187c944106SAlexei Starovoitov static int check_load(const char *file, enum bpf_prog_type type)
19e5e7a8f2SAlexei Starovoitov {
20e5e7a8f2SAlexei Starovoitov 	struct bpf_prog_load_attr attr;
2107b61991SLorenz Bauer 	struct bpf_object *obj = NULL;
22e5e7a8f2SAlexei Starovoitov 	int err, prog_fd;
23e5e7a8f2SAlexei Starovoitov 
24e5e7a8f2SAlexei Starovoitov 	memset(&attr, 0, sizeof(struct bpf_prog_load_attr));
25e5e7a8f2SAlexei Starovoitov 	attr.file = file;
267c944106SAlexei Starovoitov 	attr.prog_type = type;
27e5e7a8f2SAlexei Starovoitov 	attr.log_level = 4;
289d120b41SJiong Wang 	attr.prog_flags = BPF_F_TEST_RND_HI32;
29e5e7a8f2SAlexei Starovoitov 	err = bpf_prog_load_xattr(&attr, &obj, &prog_fd);
30e5e7a8f2SAlexei Starovoitov 	bpf_object__close(obj);
31e5e7a8f2SAlexei Starovoitov 	if (err)
32e5e7a8f2SAlexei Starovoitov 		error_cnt++;
33e5e7a8f2SAlexei Starovoitov 	return err;
34e5e7a8f2SAlexei Starovoitov }
35e5e7a8f2SAlexei Starovoitov 
36e5e7a8f2SAlexei Starovoitov void test_bpf_verif_scale(void)
37e5e7a8f2SAlexei Starovoitov {
38b061017fSAlexei Starovoitov 	const char *sched_cls[] = {
39b061017fSAlexei Starovoitov 		"./test_verif_scale1.o", "./test_verif_scale2.o", "./test_verif_scale3.o",
407c944106SAlexei Starovoitov 	};
41b061017fSAlexei Starovoitov 	const char *raw_tp[] = {
42b061017fSAlexei Starovoitov 		/* full unroll by llvm */
43b061017fSAlexei Starovoitov 		"./pyperf50.o",	"./pyperf100.o", "./pyperf180.o",
44b061017fSAlexei Starovoitov 
45b061017fSAlexei Starovoitov 		/* partial unroll. llvm will unroll loop ~150 times.
46b061017fSAlexei Starovoitov 		 * C loop count -> 600.
47b061017fSAlexei Starovoitov 		 * Asm loop count -> 4.
48b061017fSAlexei Starovoitov 		 * 16k insns in loop body.
49b061017fSAlexei Starovoitov 		 * Total of 5 such loops. Total program size ~82k insns.
50b061017fSAlexei Starovoitov 		 */
51b061017fSAlexei Starovoitov 		"./pyperf600.o",
52b061017fSAlexei Starovoitov 
53b061017fSAlexei Starovoitov 		/* no unroll at all.
54b061017fSAlexei Starovoitov 		 * C loop count -> 600.
55b061017fSAlexei Starovoitov 		 * ASM loop count -> 600.
56b061017fSAlexei Starovoitov 		 * ~110 insns in loop body.
57b061017fSAlexei Starovoitov 		 * Total of 5 such loops. Total program size ~1500 insns.
58b061017fSAlexei Starovoitov 		 */
59b061017fSAlexei Starovoitov 		"./pyperf600_nounroll.o",
60b061017fSAlexei Starovoitov 
61b061017fSAlexei Starovoitov 		"./loop1.o", "./loop2.o",
62b061017fSAlexei Starovoitov 
63b061017fSAlexei Starovoitov 		/* partial unroll. 19k insn in a loop.
64b061017fSAlexei Starovoitov 		 * Total program size 20.8k insn.
65b061017fSAlexei Starovoitov 		 * ~350k processed_insns
66b061017fSAlexei Starovoitov 		 */
67b061017fSAlexei Starovoitov 		"./strobemeta.o",
68b061017fSAlexei Starovoitov 
69b061017fSAlexei Starovoitov 		/* no unroll, tiny loops */
70b061017fSAlexei Starovoitov 		"./strobemeta_nounroll1.o",
71b061017fSAlexei Starovoitov 		"./strobemeta_nounroll2.o",
72b061017fSAlexei Starovoitov 	};
73b061017fSAlexei Starovoitov 	const char *cg_sysctl[] = {
74b061017fSAlexei Starovoitov 		"./test_sysctl_loop1.o", "./test_sysctl_loop2.o",
757c944106SAlexei Starovoitov 	};
76329e38f7SAndrii Nakryiko 	libbpf_print_fn_t old_print_fn = NULL;
777c944106SAlexei Starovoitov 	int err, i;
78e5e7a8f2SAlexei Starovoitov 
790ff97e56SAndrii Nakryiko 	if (env.verifier_stats) {
800ff97e56SAndrii Nakryiko 		test__force_log();
81329e38f7SAndrii Nakryiko 		old_print_fn = libbpf_set_print(libbpf_debug_print);
820ff97e56SAndrii Nakryiko 	}
83e5e7a8f2SAlexei Starovoitov 
84b061017fSAlexei Starovoitov 	err = check_load("./loop3.o", BPF_PROG_TYPE_RAW_TRACEPOINT);
850ff97e56SAndrii Nakryiko 	test__printf("test_scale:loop3:%s\n",
860ff97e56SAndrii Nakryiko 		     err ? (error_cnt--, "OK") : "FAIL");
87b061017fSAlexei Starovoitov 
88b061017fSAlexei Starovoitov 	for (i = 0; i < ARRAY_SIZE(sched_cls); i++) {
89b061017fSAlexei Starovoitov 		err = check_load(sched_cls[i], BPF_PROG_TYPE_SCHED_CLS);
900ff97e56SAndrii Nakryiko 		test__printf("test_scale:%s:%s\n", sched_cls[i],
910ff97e56SAndrii Nakryiko 			     err ? "FAIL" : "OK");
927c944106SAlexei Starovoitov 	}
937c944106SAlexei Starovoitov 
94b061017fSAlexei Starovoitov 	for (i = 0; i < ARRAY_SIZE(raw_tp); i++) {
95b061017fSAlexei Starovoitov 		err = check_load(raw_tp[i], BPF_PROG_TYPE_RAW_TRACEPOINT);
960ff97e56SAndrii Nakryiko 		test__printf("test_scale:%s:%s\n", raw_tp[i],
970ff97e56SAndrii Nakryiko 			     err ? "FAIL" : "OK");
987c944106SAlexei Starovoitov 	}
99b061017fSAlexei Starovoitov 
100b061017fSAlexei Starovoitov 	for (i = 0; i < ARRAY_SIZE(cg_sysctl); i++) {
101b061017fSAlexei Starovoitov 		err = check_load(cg_sysctl[i], BPF_PROG_TYPE_CGROUP_SYSCTL);
1020ff97e56SAndrii Nakryiko 		test__printf("test_scale:%s:%s\n", cg_sysctl[i],
1030ff97e56SAndrii Nakryiko 			     err ? "FAIL" : "OK");
104b061017fSAlexei Starovoitov 	}
105b061017fSAlexei Starovoitov 	err = check_load("./test_xdp_loop.o", BPF_PROG_TYPE_XDP);
1060ff97e56SAndrii Nakryiko 	test__printf("test_scale:test_xdp_loop:%s\n", err ? "FAIL" : "OK");
107b061017fSAlexei Starovoitov 
108b061017fSAlexei Starovoitov 	err = check_load("./test_seg6_loop.o", BPF_PROG_TYPE_LWT_SEG6LOCAL);
1090ff97e56SAndrii Nakryiko 	test__printf("test_scale:test_seg6_loop:%s\n", err ? "FAIL" : "OK");
110329e38f7SAndrii Nakryiko 
1110ff97e56SAndrii Nakryiko 	if (env.verifier_stats)
112329e38f7SAndrii Nakryiko 		libbpf_set_print(old_print_fn);
113e5e7a8f2SAlexei Starovoitov }
114