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) {
866bd2ec1SStanislav Fomichev 		vprintf(format, args);
90ff97e56SAndrii Nakryiko 		return 0;
100ff97e56SAndrii Nakryiko 	}
11e5e7a8f2SAlexei Starovoitov 
12e5e7a8f2SAlexei Starovoitov 	if (!strstr(format, "verifier log"))
13e5e7a8f2SAlexei Starovoitov 		return 0;
1466bd2ec1SStanislav Fomichev 	vprintf("%s", args);
150ff97e56SAndrii Nakryiko 	return 0;
16e5e7a8f2SAlexei Starovoitov }
17e5e7a8f2SAlexei Starovoitov 
18a8fdaad5SAndrii Nakryiko extern int extra_prog_load_log_flags;
19a8fdaad5SAndrii Nakryiko 
207c944106SAlexei Starovoitov static int check_load(const char *file, enum bpf_prog_type type)
21e5e7a8f2SAlexei Starovoitov {
2207b61991SLorenz Bauer 	struct bpf_object *obj = NULL;
23*186d1a86SAndrii Nakryiko 	struct bpf_program *prog;
24*186d1a86SAndrii Nakryiko 	int err;
25e5e7a8f2SAlexei Starovoitov 
26*186d1a86SAndrii Nakryiko 	obj = bpf_object__open_file(file, NULL);
27*186d1a86SAndrii Nakryiko 	err = libbpf_get_error(obj);
28*186d1a86SAndrii Nakryiko 	if (err)
29*186d1a86SAndrii Nakryiko 		return err;
30*186d1a86SAndrii Nakryiko 
31*186d1a86SAndrii Nakryiko 	prog = bpf_object__next_program(obj, NULL);
32*186d1a86SAndrii Nakryiko 	if (!prog) {
33*186d1a86SAndrii Nakryiko 		err = -ENOENT;
34*186d1a86SAndrii Nakryiko 		goto err_out;
35*186d1a86SAndrii Nakryiko 	}
36*186d1a86SAndrii Nakryiko 
37*186d1a86SAndrii Nakryiko 	bpf_program__set_type(prog, type);
38*186d1a86SAndrii Nakryiko 	bpf_program__set_flags(prog, BPF_F_TEST_RND_HI32);
39*186d1a86SAndrii Nakryiko 	bpf_program__set_log_level(prog, 4 | extra_prog_load_log_flags);
40*186d1a86SAndrii Nakryiko 
41*186d1a86SAndrii Nakryiko 	err = bpf_object__load(obj);
42*186d1a86SAndrii Nakryiko 
43*186d1a86SAndrii Nakryiko err_out:
44e5e7a8f2SAlexei Starovoitov 	bpf_object__close(obj);
45e5e7a8f2SAlexei Starovoitov 	return err;
46e5e7a8f2SAlexei Starovoitov }
47e5e7a8f2SAlexei Starovoitov 
4851436ed7SAndrii Nakryiko struct scale_test_def {
4951436ed7SAndrii Nakryiko 	const char *file;
5051436ed7SAndrii Nakryiko 	enum bpf_prog_type attach_type;
5151436ed7SAndrii Nakryiko 	bool fails;
5251436ed7SAndrii Nakryiko };
5351436ed7SAndrii Nakryiko 
543762a39cSAndrii Nakryiko static void scale_test(const char *file,
553762a39cSAndrii Nakryiko 		       enum bpf_prog_type attach_type,
563762a39cSAndrii Nakryiko 		       bool should_fail)
57e5e7a8f2SAlexei Starovoitov {
58329e38f7SAndrii Nakryiko 	libbpf_print_fn_t old_print_fn = NULL;
593762a39cSAndrii Nakryiko 	int err;
60e5e7a8f2SAlexei Starovoitov 
610ff97e56SAndrii Nakryiko 	if (env.verifier_stats) {
620ff97e56SAndrii Nakryiko 		test__force_log();
63329e38f7SAndrii Nakryiko 		old_print_fn = libbpf_set_print(libbpf_debug_print);
640ff97e56SAndrii Nakryiko 	}
65e5e7a8f2SAlexei Starovoitov 
663762a39cSAndrii Nakryiko 	err = check_load(file, attach_type);
673762a39cSAndrii Nakryiko 	if (should_fail)
683762a39cSAndrii Nakryiko 		ASSERT_ERR(err, "expect_error");
693762a39cSAndrii Nakryiko 	else
703762a39cSAndrii Nakryiko 		ASSERT_OK(err, "expect_success");
71b061017fSAlexei Starovoitov 
720ff97e56SAndrii Nakryiko 	if (env.verifier_stats)
73329e38f7SAndrii Nakryiko 		libbpf_set_print(old_print_fn);
74e5e7a8f2SAlexei Starovoitov }
753762a39cSAndrii Nakryiko 
763762a39cSAndrii Nakryiko void test_verif_scale1()
773762a39cSAndrii Nakryiko {
783762a39cSAndrii Nakryiko 	scale_test("test_verif_scale1.o", BPF_PROG_TYPE_SCHED_CLS, false);
793762a39cSAndrii Nakryiko }
803762a39cSAndrii Nakryiko 
813762a39cSAndrii Nakryiko void test_verif_scale2()
823762a39cSAndrii Nakryiko {
833762a39cSAndrii Nakryiko 	scale_test("test_verif_scale2.o", BPF_PROG_TYPE_SCHED_CLS, false);
843762a39cSAndrii Nakryiko }
853762a39cSAndrii Nakryiko 
863762a39cSAndrii Nakryiko void test_verif_scale3()
873762a39cSAndrii Nakryiko {
883762a39cSAndrii Nakryiko 	scale_test("test_verif_scale3.o", BPF_PROG_TYPE_SCHED_CLS, false);
893762a39cSAndrii Nakryiko }
903762a39cSAndrii Nakryiko 
913762a39cSAndrii Nakryiko void test_verif_scale_pyperf_global()
923762a39cSAndrii Nakryiko {
933762a39cSAndrii Nakryiko 	scale_test("pyperf_global.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false);
943762a39cSAndrii Nakryiko }
953762a39cSAndrii Nakryiko 
963762a39cSAndrii Nakryiko void test_verif_scale_pyperf_subprogs()
973762a39cSAndrii Nakryiko {
983762a39cSAndrii Nakryiko 	scale_test("pyperf_subprogs.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false);
993762a39cSAndrii Nakryiko }
1003762a39cSAndrii Nakryiko 
1013762a39cSAndrii Nakryiko void test_verif_scale_pyperf50()
1023762a39cSAndrii Nakryiko {
1033762a39cSAndrii Nakryiko 	/* full unroll by llvm */
1043762a39cSAndrii Nakryiko 	scale_test("pyperf50.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false);
1053762a39cSAndrii Nakryiko }
1063762a39cSAndrii Nakryiko 
1073762a39cSAndrii Nakryiko void test_verif_scale_pyperf100()
1083762a39cSAndrii Nakryiko {
1093762a39cSAndrii Nakryiko 	/* full unroll by llvm */
1103762a39cSAndrii Nakryiko 	scale_test("pyperf100.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false);
1113762a39cSAndrii Nakryiko }
1123762a39cSAndrii Nakryiko 
1133762a39cSAndrii Nakryiko void test_verif_scale_pyperf180()
1143762a39cSAndrii Nakryiko {
1153762a39cSAndrii Nakryiko 	/* full unroll by llvm */
1163762a39cSAndrii Nakryiko 	scale_test("pyperf180.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false);
1173762a39cSAndrii Nakryiko }
1183762a39cSAndrii Nakryiko 
1193762a39cSAndrii Nakryiko void test_verif_scale_pyperf600()
1203762a39cSAndrii Nakryiko {
1213762a39cSAndrii Nakryiko 	/* partial unroll. llvm will unroll loop ~150 times.
1223762a39cSAndrii Nakryiko 	 * C loop count -> 600.
1233762a39cSAndrii Nakryiko 	 * Asm loop count -> 4.
1243762a39cSAndrii Nakryiko 	 * 16k insns in loop body.
1253762a39cSAndrii Nakryiko 	 * Total of 5 such loops. Total program size ~82k insns.
1263762a39cSAndrii Nakryiko 	 */
1273762a39cSAndrii Nakryiko 	scale_test("pyperf600.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false);
1283762a39cSAndrii Nakryiko }
1293762a39cSAndrii Nakryiko 
130f6e659b7SJoanne Koong void test_verif_scale_pyperf600_bpf_loop(void)
131f6e659b7SJoanne Koong {
132f6e659b7SJoanne Koong 	/* use the bpf_loop helper*/
133f6e659b7SJoanne Koong 	scale_test("pyperf600_bpf_loop.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false);
134f6e659b7SJoanne Koong }
135f6e659b7SJoanne Koong 
1363762a39cSAndrii Nakryiko void test_verif_scale_pyperf600_nounroll()
1373762a39cSAndrii Nakryiko {
1383762a39cSAndrii Nakryiko 	/* no unroll at all.
1393762a39cSAndrii Nakryiko 	 * C loop count -> 600.
1403762a39cSAndrii Nakryiko 	 * ASM loop count -> 600.
1413762a39cSAndrii Nakryiko 	 * ~110 insns in loop body.
1423762a39cSAndrii Nakryiko 	 * Total of 5 such loops. Total program size ~1500 insns.
1433762a39cSAndrii Nakryiko 	 */
1443762a39cSAndrii Nakryiko 	scale_test("pyperf600_nounroll.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false);
1453762a39cSAndrii Nakryiko }
1463762a39cSAndrii Nakryiko 
1473762a39cSAndrii Nakryiko void test_verif_scale_loop1()
1483762a39cSAndrii Nakryiko {
1493762a39cSAndrii Nakryiko 	scale_test("loop1.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false);
1503762a39cSAndrii Nakryiko }
1513762a39cSAndrii Nakryiko 
1523762a39cSAndrii Nakryiko void test_verif_scale_loop2()
1533762a39cSAndrii Nakryiko {
1543762a39cSAndrii Nakryiko 	scale_test("loop2.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false);
1553762a39cSAndrii Nakryiko }
1563762a39cSAndrii Nakryiko 
1573762a39cSAndrii Nakryiko void test_verif_scale_loop3_fail()
1583762a39cSAndrii Nakryiko {
1593762a39cSAndrii Nakryiko 	scale_test("loop3.o", BPF_PROG_TYPE_RAW_TRACEPOINT, true /* fails */);
1603762a39cSAndrii Nakryiko }
1613762a39cSAndrii Nakryiko 
1623762a39cSAndrii Nakryiko void test_verif_scale_loop4()
1633762a39cSAndrii Nakryiko {
1643762a39cSAndrii Nakryiko 	scale_test("loop4.o", BPF_PROG_TYPE_SCHED_CLS, false);
1653762a39cSAndrii Nakryiko }
1663762a39cSAndrii Nakryiko 
1673762a39cSAndrii Nakryiko void test_verif_scale_loop5()
1683762a39cSAndrii Nakryiko {
1693762a39cSAndrii Nakryiko 	scale_test("loop5.o", BPF_PROG_TYPE_SCHED_CLS, false);
1703762a39cSAndrii Nakryiko }
1713762a39cSAndrii Nakryiko 
1723762a39cSAndrii Nakryiko void test_verif_scale_loop6()
1733762a39cSAndrii Nakryiko {
1743762a39cSAndrii Nakryiko 	scale_test("loop6.o", BPF_PROG_TYPE_KPROBE, false);
1753762a39cSAndrii Nakryiko }
1763762a39cSAndrii Nakryiko 
1773762a39cSAndrii Nakryiko void test_verif_scale_strobemeta()
1783762a39cSAndrii Nakryiko {
1793762a39cSAndrii Nakryiko 	/* partial unroll. 19k insn in a loop.
1803762a39cSAndrii Nakryiko 	 * Total program size 20.8k insn.
1813762a39cSAndrii Nakryiko 	 * ~350k processed_insns
1823762a39cSAndrii Nakryiko 	 */
1833762a39cSAndrii Nakryiko 	scale_test("strobemeta.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false);
1843762a39cSAndrii Nakryiko }
1853762a39cSAndrii Nakryiko 
186f6e659b7SJoanne Koong void test_verif_scale_strobemeta_bpf_loop(void)
187f6e659b7SJoanne Koong {
188f6e659b7SJoanne Koong 	/* use the bpf_loop helper*/
189f6e659b7SJoanne Koong 	scale_test("strobemeta_bpf_loop.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false);
190f6e659b7SJoanne Koong }
191f6e659b7SJoanne Koong 
1923762a39cSAndrii Nakryiko void test_verif_scale_strobemeta_nounroll1()
1933762a39cSAndrii Nakryiko {
1943762a39cSAndrii Nakryiko 	/* no unroll, tiny loops */
1953762a39cSAndrii Nakryiko 	scale_test("strobemeta_nounroll1.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false);
1963762a39cSAndrii Nakryiko }
1973762a39cSAndrii Nakryiko 
1983762a39cSAndrii Nakryiko void test_verif_scale_strobemeta_nounroll2()
1993762a39cSAndrii Nakryiko {
2003762a39cSAndrii Nakryiko 	/* no unroll, tiny loops */
2013762a39cSAndrii Nakryiko 	scale_test("strobemeta_nounroll2.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false);
2023762a39cSAndrii Nakryiko }
2033762a39cSAndrii Nakryiko 
2043762a39cSAndrii Nakryiko void test_verif_scale_strobemeta_subprogs()
2053762a39cSAndrii Nakryiko {
2063762a39cSAndrii Nakryiko 	/* non-inlined subprogs */
2073762a39cSAndrii Nakryiko 	scale_test("strobemeta_subprogs.o", BPF_PROG_TYPE_RAW_TRACEPOINT, false);
2083762a39cSAndrii Nakryiko }
2093762a39cSAndrii Nakryiko 
2103762a39cSAndrii Nakryiko void test_verif_scale_sysctl_loop1()
2113762a39cSAndrii Nakryiko {
2123762a39cSAndrii Nakryiko 	scale_test("test_sysctl_loop1.o", BPF_PROG_TYPE_CGROUP_SYSCTL, false);
2133762a39cSAndrii Nakryiko }
2143762a39cSAndrii Nakryiko 
2153762a39cSAndrii Nakryiko void test_verif_scale_sysctl_loop2()
2163762a39cSAndrii Nakryiko {
2173762a39cSAndrii Nakryiko 	scale_test("test_sysctl_loop2.o", BPF_PROG_TYPE_CGROUP_SYSCTL, false);
2183762a39cSAndrii Nakryiko }
2193762a39cSAndrii Nakryiko 
2203762a39cSAndrii Nakryiko void test_verif_scale_xdp_loop()
2213762a39cSAndrii Nakryiko {
2223762a39cSAndrii Nakryiko 	scale_test("test_xdp_loop.o", BPF_PROG_TYPE_XDP, false);
2233762a39cSAndrii Nakryiko }
2243762a39cSAndrii Nakryiko 
2253762a39cSAndrii Nakryiko void test_verif_scale_seg6_loop()
2263762a39cSAndrii Nakryiko {
2273762a39cSAndrii Nakryiko 	scale_test("test_seg6_loop.o", BPF_PROG_TYPE_LWT_SEG6LOCAL, false);
2283762a39cSAndrii Nakryiko }
2290869e507SAlexei Starovoitov 
2300869e507SAlexei Starovoitov void test_verif_twfw()
2310869e507SAlexei Starovoitov {
2320869e507SAlexei Starovoitov 	scale_test("twfw.o", BPF_PROG_TYPE_CGROUP_SKB, false);
2330869e507SAlexei Starovoitov }
234