1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (c) 2025 Meta Platforms, Inc. and affiliates.
4 * Copyright (c) 2025 Tejun Heo <tj@kernel.org>
5 */
6#include <stdio.h>
7#include <unistd.h>
8#include <signal.h>
9#include <assert.h>
10#include <libgen.h>
11#include <bpf/bpf.h>
12#include <scx/common.h>
13#include "scx_cpu0.bpf.skel.h"
14
15const char help_fmt[] =
16"A cpu0 sched_ext scheduler.\n"
17"\n"
18"See the top-level comment in .bpf.c for more details.\n"
19"\n"
20"Usage: %s [-v]\n"
21"\n"
22" -v Print libbpf debug messages\n"
23" -h Display this help and exit\n";
24
25static bool verbose;
26static volatile int exit_req;
27
28static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args)
29{
30 if (level == LIBBPF_DEBUG && !verbose)
31 return 0;
32 return vfprintf(stderr, format, args);
33}
34
35static void sigint_handler(int sig)
36{
37 exit_req = 1;
38}
39
40static void read_stats(struct scx_cpu0 *skel, __u64 *stats)
41{
42 int nr_cpus = libbpf_num_possible_cpus();
43 assert(nr_cpus > 0);
44 __u64 cnts[2][nr_cpus];
45 __u32 idx;
46
47 memset(stats, 0, sizeof(stats[0]) * 2);
48
49 for (idx = 0; idx < 2; idx++) {
50 int ret, cpu;
51
52 ret = bpf_map_lookup_elem(bpf_map__fd(skel->maps.stats),
53 &idx, cnts[idx]);
54 if (ret < 0)
55 continue;
56 for (cpu = 0; cpu < nr_cpus; cpu++)
57 stats[idx] += cnts[idx][cpu];
58 }
59}
60
61int main(int argc, char **argv)
62{
63 struct scx_cpu0 *skel;
64 struct bpf_link *link;
65 __u32 opt;
66 __u64 ecode;
67
68 libbpf_set_print(libbpf_print_fn);
69 signal(SIGINT, sigint_handler);
70 signal(SIGTERM, sigint_handler);
71restart:
72 skel = SCX_OPS_OPEN(cpu0_ops, scx_cpu0);
73
74 skel->rodata->nr_cpus = libbpf_num_possible_cpus();
75
76 while ((opt = getopt(argc, argv, "vh")) != -1) {
77 switch (opt) {
78 case 'v':
79 verbose = true;
80 break;
81 default:
82 fprintf(stderr, help_fmt, basename(argv[0]));
83 return opt != 'h';
84 }
85 }
86
87 SCX_OPS_LOAD(skel, cpu0_ops, scx_cpu0, uei);
88 link = SCX_OPS_ATTACH(skel, cpu0_ops, scx_cpu0);
89
90 while (!exit_req && !UEI_EXITED(skel, uei)) {
91 __u64 stats[2];
92
93 read_stats(skel, stats);
94 printf("local=%llu cpu0=%llu\n", stats[0], stats[1]);
95 fflush(stdout);
96 sleep(1);
97 }
98
99 bpf_link__destroy(link);
100 ecode = UEI_REPORT(skel, uei);
101 scx_cpu0__destroy(skel);
102
103 if (UEI_ECODE_RESTART(ecode))
104 goto restart;
105 return 0;
106}
107

source code of linux/tools/sched_ext/scx_cpu0.c