108 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2/*3 * Copyright (c) 2022 Meta Platforms, Inc. and affiliates.4 * Copyright (c) 2022 Tejun Heo <tj@kernel.org>5 * Copyright (c) 2022 David Vernet <dvernet@meta.com>6 */7#include <stdio.h>8#include <unistd.h>9#include <signal.h>10#include <libgen.h>11#include <bpf/bpf.h>12#include <scx/common.h>13#include "scx_simple.bpf.skel.h"14 15const char help_fmt[] =16"A simple sched_ext scheduler.\n"17"\n"18"See the top-level comment in .bpf.c for more details.\n"19"\n"20"Usage: %s [-f] [-v]\n"21"\n"22" -f Use FIFO scheduling instead of weighted vtime scheduling\n"23" -v Print libbpf debug messages\n"24" -h Display this help and exit\n";25 26static bool verbose;27static volatile int exit_req;28 29static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args)30{31 if (level == LIBBPF_DEBUG && !verbose)32 return 0;33 return vfprintf(stderr, format, args);34}35 36static void sigint_handler(int simple)37{38 exit_req = 1;39}40 41static void read_stats(struct scx_simple *skel, __u64 *stats)42{43 int nr_cpus = libbpf_num_possible_cpus();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_simple *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(simple_ops, scx_simple);73 74 while ((opt = getopt(argc, argv, "fvh")) != -1) {75 switch (opt) {76 case 'f':77 skel->rodata->fifo_sched = true;78 break;79 case 'v':80 verbose = true;81 break;82 default:83 fprintf(stderr, help_fmt, basename(argv[0]));84 return opt != 'h';85 }86 }87 88 SCX_OPS_LOAD(skel, simple_ops, scx_simple, uei);89 link = SCX_OPS_ATTACH(skel, simple_ops, scx_simple);90 91 while (!exit_req && !UEI_EXITED(skel, uei)) {92 __u64 stats[2];93 94 read_stats(skel, stats);95 printf("local=%llu global=%llu\n", stats[0], stats[1]);96 fflush(stdout);97 sleep(1);98 }99 100 bpf_link__destroy(link);101 ecode = UEI_REPORT(skel, uei);102 scx_simple__destroy(skel);103 104 if (UEI_ECODE_RESTART(ecode))105 goto restart;106 return 0;107}108