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
libbpf_print_fn(enum libbpf_print_level level,const char * format,va_list args)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
sigint_handler(int sig)38 static void sigint_handler(int sig)
39 {
40 exit_req = 1;
41 }
42
main(int argc,char ** argv)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