brintos

brintos / linux-shallow public Read only

0
0
Text · 3.8 KiB · 21deea3 Raw
136 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#define _GNU_SOURCE8#include <sched.h>9#include <stdio.h>10#include <unistd.h>11#include <inttypes.h>12#include <signal.h>13#include <libgen.h>14#include <bpf/bpf.h>15#include <scx/common.h>16#include "scx_central.bpf.skel.h"17 18const char help_fmt[] =19"A central FIFO sched_ext scheduler.\n"20"\n"21"See the top-level comment in .bpf.c for more details.\n"22"\n"23"Usage: %s [-s SLICE_US] [-c CPU]\n"24"\n"25"  -s SLICE_US   Override slice duration\n"26"  -c CPU        Override the central CPU (default: 0)\n"27"  -v            Print libbpf debug messages\n"28"  -h            Display this help and exit\n";29 30static bool verbose;31static volatile int exit_req;32 33static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args)34{35	if (level == LIBBPF_DEBUG && !verbose)36		return 0;37	return vfprintf(stderr, format, args);38}39 40static void sigint_handler(int dummy)41{42	exit_req = 1;43}44 45int main(int argc, char **argv)46{47	struct scx_central *skel;48	struct bpf_link *link;49	__u64 seq = 0, ecode;50	__s32 opt;51	cpu_set_t *cpuset;52 53	libbpf_set_print(libbpf_print_fn);54	signal(SIGINT, sigint_handler);55	signal(SIGTERM, sigint_handler);56restart:57	skel = SCX_OPS_OPEN(central_ops, scx_central);58 59	skel->rodata->central_cpu = 0;60	skel->rodata->nr_cpu_ids = libbpf_num_possible_cpus();61 62	while ((opt = getopt(argc, argv, "s:c:pvh")) != -1) {63		switch (opt) {64		case 's':65			skel->rodata->slice_ns = strtoull(optarg, NULL, 0) * 1000;66			break;67		case 'c':68			skel->rodata->central_cpu = strtoul(optarg, NULL, 0);69			break;70		case 'v':71			verbose = true;72			break;73		default:74			fprintf(stderr, help_fmt, basename(argv[0]));75			return opt != 'h';76		}77	}78 79	/* Resize arrays so their element count is equal to cpu count. */80	RESIZE_ARRAY(skel, data, cpu_gimme_task, skel->rodata->nr_cpu_ids);81	RESIZE_ARRAY(skel, data, cpu_started_at, skel->rodata->nr_cpu_ids);82 83	SCX_OPS_LOAD(skel, central_ops, scx_central, uei);84 85	/*86	 * Affinitize the loading thread to the central CPU, as:87	 * - That's where the BPF timer is first invoked in the BPF program.88	 * - We probably don't want this user space component to take up a core89	 *   from a task that would benefit from avoiding preemption on one of90	 *   the tickless cores.91	 *92	 * Until BPF supports pinning the timer, it's not guaranteed that it93	 * will always be invoked on the central CPU. In practice, this94	 * suffices the majority of the time.95	 */96	cpuset = CPU_ALLOC(skel->rodata->nr_cpu_ids);97	SCX_BUG_ON(!cpuset, "Failed to allocate cpuset");98	CPU_ZERO(cpuset);99	CPU_SET(skel->rodata->central_cpu, cpuset);100	SCX_BUG_ON(sched_setaffinity(0, sizeof(cpuset), cpuset),101		   "Failed to affinitize to central CPU %d (max %d)",102		   skel->rodata->central_cpu, skel->rodata->nr_cpu_ids - 1);103	CPU_FREE(cpuset);104 105	link = SCX_OPS_ATTACH(skel, central_ops, scx_central);106 107	if (!skel->data->timer_pinned)108		printf("WARNING : BPF_F_TIMER_CPU_PIN not available, timer not pinned to central\n");109 110	while (!exit_req && !UEI_EXITED(skel, uei)) {111		printf("[SEQ %llu]\n", seq++);112		printf("total   :%10" PRIu64 "    local:%10" PRIu64 "   queued:%10" PRIu64 "  lost:%10" PRIu64 "\n",113		       skel->bss->nr_total,114		       skel->bss->nr_locals,115		       skel->bss->nr_queued,116		       skel->bss->nr_lost_pids);117		printf("timer   :%10" PRIu64 " dispatch:%10" PRIu64 " mismatch:%10" PRIu64 " retry:%10" PRIu64 "\n",118		       skel->bss->nr_timers,119		       skel->bss->nr_dispatches,120		       skel->bss->nr_mismatches,121		       skel->bss->nr_retries);122		printf("overflow:%10" PRIu64 "\n",123		       skel->bss->nr_overflows);124		fflush(stdout);125		sleep(1);126	}127 128	bpf_link__destroy(link);129	ecode = UEI_REPORT(skel, uei);130	scx_central__destroy(skel);131 132	if (UEI_ECODE_RESTART(ecode))133		goto restart;134	return 0;135}136