xref: /linux/tools/sched_ext/scx_sdt.c (revision bf4afc53b77aeaa48b5409da5c8da6bb4eff7f43)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (c) 2024 Meta Platforms, Inc. and affiliates.
4  * Copyright (c) 2024 Emil Tsalapatis <etsal@meta.com>
5  * Copyright (c) 2024 Tejun Heo <tj@kernel.org>
6  * Copyright (c) 2022 David Vernet <dvernet@meta.com>
7  */
8 #include <stdio.h>
9 #include <unistd.h>
10 #include <signal.h>
11 #include <libgen.h>
12 #include <bpf/bpf.h>
13 #include <scx/common.h>
14 
15 #include "scx_sdt.h"
16 #include "scx_sdt.bpf.skel.h"
17 
18 const char help_fmt[] =
19 "A simple arena-based sched_ext scheduler.\n"
20 "\n"
21 "Modified version of scx_simple that demonstrates arena-based data structures.\n"
22 "\n"
23 "Usage: %s [-f] [-v]\n"
24 "\n"
25 "  -v            Print libbpf debug messages\n"
26 "  -h            Display this help and exit\n";
27 
28 static bool verbose;
29 static volatile int exit_req;
30 
31 static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args)
32 {
33 	if (level == LIBBPF_DEBUG && !verbose)
34 		return 0;
35 	return vfprintf(stderr, format, args);
36 }
37 
38 static void sigint_handler(int sig)
39 {
40 	exit_req = 1;
41 }
42 
43 int main(int argc, char **argv)
44 {
45 	struct scx_sdt *skel;
46 	struct bpf_link *link;
47 	__u32 opt;
48 	__u64 ecode;
49 
50 	libbpf_set_print(libbpf_print_fn);
51 	signal(SIGINT, sigint_handler);
52 	signal(SIGTERM, sigint_handler);
53 restart:
54 	optind = 1;
55 	skel = SCX_OPS_OPEN(sdt_ops, scx_sdt);
56 
57 	while ((opt = getopt(argc, argv, "fvh")) != -1) {
58 		switch (opt) {
59 		case 'v':
60 			verbose = true;
61 			break;
62 		default:
63 			fprintf(stderr, help_fmt, basename(argv[0]));
64 			return opt != 'h';
65 		}
66 	}
67 
68 	SCX_OPS_LOAD(skel, sdt_ops, scx_sdt, uei);
69 	link = SCX_OPS_ATTACH(skel, sdt_ops, scx_sdt);
70 
71 	while (!exit_req && !UEI_EXITED(skel, uei)) {
72 		printf("====SCHEDULING STATS====\n");
73 		printf("enqueues=%llu\t", skel->bss->stat_enqueue);
74 		printf("inits=%llu\t", skel->bss->stat_init);
75 		printf("exits=%llu\t", skel->bss->stat_exit);
76 		printf("\n");
77 
78 		printf("select_idle_cpu=%llu\t", skel->bss->stat_select_idle_cpu);
79 		printf("select_busy_cpu=%llu\t", skel->bss->stat_select_busy_cpu);
80 		printf("\n");
81 
82 		printf("====ALLOCATION STATS====\n");
83 		printf("chunk allocs=%llu\t", skel->bss->alloc_stats.chunk_allocs);
84 		printf("data_allocs=%llu\n", skel->bss->alloc_stats.data_allocs);
85 		printf("alloc_ops=%llu\t", skel->bss->alloc_stats.alloc_ops);
86 		printf("free_ops=%llu\t", skel->bss->alloc_stats.free_ops);
87 		printf("active_allocs=%llu\t", skel->bss->alloc_stats.active_allocs);
88 		printf("arena_pages_used=%llu\t", skel->bss->alloc_stats.arena_pages_used);
89 		printf("\n\n");
90 
91 		fflush(stdout);
92 		sleep(1);
93 	}
94 
95 	bpf_link__destroy(link);
96 	ecode = UEI_REPORT(skel, uei);
97 	scx_sdt__destroy(skel);
98 
99 	if (UEI_ECODE_RESTART(ecode))
100 		goto restart;
101 	return 0;
102 }
103