brintos

brintos / linux-shallow public Read only

0
0
Text · 4.6 KiB · ac45a02 Raw
154 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 <stdlib.h>9#include <unistd.h>10#include <inttypes.h>11#include <signal.h>12#include <libgen.h>13#include <bpf/bpf.h>14#include <scx/common.h>15#include "scx_qmap.bpf.skel.h"16 17const char help_fmt[] =18"A simple five-level FIFO queue sched_ext scheduler.\n"19"\n"20"See the top-level comment in .bpf.c for more details.\n"21"\n"22"Usage: %s [-s SLICE_US] [-e COUNT] [-t COUNT] [-T COUNT] [-l COUNT] [-b COUNT]\n"23"       [-P] [-d PID] [-D LEN] [-p] [-v]\n"24"\n"25"  -s SLICE_US   Override slice duration\n"26"  -e COUNT      Trigger scx_bpf_error() after COUNT enqueues\n"27"  -t COUNT      Stall every COUNT'th user thread\n"28"  -T COUNT      Stall every COUNT'th kernel thread\n"29"  -l COUNT      Trigger dispatch infinite looping after COUNT dispatches\n"30"  -b COUNT      Dispatch upto COUNT tasks together\n"31"  -P            Print out DSQ content to trace_pipe every second, use with -b\n"32"  -H            Boost nice -20 tasks in SHARED_DSQ, use with -b\n"33"  -d PID        Disallow a process from switching into SCHED_EXT (-1 for self)\n"34"  -D LEN        Set scx_exit_info.dump buffer length\n"35"  -S            Suppress qmap-specific debug dump\n"36"  -p            Switch only tasks on SCHED_EXT policy instead of all\n"37"  -v            Print libbpf debug messages\n"38"  -h            Display this help and exit\n";39 40static bool verbose;41static volatile int exit_req;42 43static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args)44{45	if (level == LIBBPF_DEBUG && !verbose)46		return 0;47	return vfprintf(stderr, format, args);48}49 50static void sigint_handler(int dummy)51{52	exit_req = 1;53}54 55int main(int argc, char **argv)56{57	struct scx_qmap *skel;58	struct bpf_link *link;59	int opt;60 61	libbpf_set_print(libbpf_print_fn);62	signal(SIGINT, sigint_handler);63	signal(SIGTERM, sigint_handler);64 65	skel = SCX_OPS_OPEN(qmap_ops, scx_qmap);66 67	while ((opt = getopt(argc, argv, "s:e:t:T:l:b:PHd:D:Spvh")) != -1) {68		switch (opt) {69		case 's':70			skel->rodata->slice_ns = strtoull(optarg, NULL, 0) * 1000;71			break;72		case 'e':73			skel->bss->test_error_cnt = strtoul(optarg, NULL, 0);74			break;75		case 't':76			skel->rodata->stall_user_nth = strtoul(optarg, NULL, 0);77			break;78		case 'T':79			skel->rodata->stall_kernel_nth = strtoul(optarg, NULL, 0);80			break;81		case 'l':82			skel->rodata->dsp_inf_loop_after = strtoul(optarg, NULL, 0);83			break;84		case 'b':85			skel->rodata->dsp_batch = strtoul(optarg, NULL, 0);86			break;87		case 'P':88			skel->rodata->print_shared_dsq = true;89			break;90		case 'H':91			skel->rodata->highpri_boosting = true;92			break;93		case 'd':94			skel->rodata->disallow_tgid = strtol(optarg, NULL, 0);95			if (skel->rodata->disallow_tgid < 0)96				skel->rodata->disallow_tgid = getpid();97			break;98		case 'D':99			skel->struct_ops.qmap_ops->exit_dump_len = strtoul(optarg, NULL, 0);100			break;101		case 'S':102			skel->rodata->suppress_dump = true;103			break;104		case 'p':105			skel->struct_ops.qmap_ops->flags |= SCX_OPS_SWITCH_PARTIAL;106			break;107		case 'v':108			verbose = true;109			break;110		default:111			fprintf(stderr, help_fmt, basename(argv[0]));112			return opt != 'h';113		}114	}115 116	SCX_OPS_LOAD(skel, qmap_ops, scx_qmap, uei);117	link = SCX_OPS_ATTACH(skel, qmap_ops, scx_qmap);118 119	while (!exit_req && !UEI_EXITED(skel, uei)) {120		long nr_enqueued = skel->bss->nr_enqueued;121		long nr_dispatched = skel->bss->nr_dispatched;122 123		printf("stats  : enq=%lu dsp=%lu delta=%ld reenq=%"PRIu64" deq=%"PRIu64" core=%"PRIu64" enq_ddsp=%"PRIu64"\n",124		       nr_enqueued, nr_dispatched, nr_enqueued - nr_dispatched,125		       skel->bss->nr_reenqueued, skel->bss->nr_dequeued,126		       skel->bss->nr_core_sched_execed,127		       skel->bss->nr_ddsp_from_enq);128		printf("         exp_local=%"PRIu64" exp_remote=%"PRIu64" exp_timer=%"PRIu64" exp_lost=%"PRIu64"\n",129		       skel->bss->nr_expedited_local,130		       skel->bss->nr_expedited_remote,131		       skel->bss->nr_expedited_from_timer,132		       skel->bss->nr_expedited_lost);133		if (__COMPAT_has_ksym("scx_bpf_cpuperf_cur"))134			printf("cpuperf: cur min/avg/max=%u/%u/%u target min/avg/max=%u/%u/%u\n",135			       skel->bss->cpuperf_min,136			       skel->bss->cpuperf_avg,137			       skel->bss->cpuperf_max,138			       skel->bss->cpuperf_target_min,139			       skel->bss->cpuperf_target_avg,140			       skel->bss->cpuperf_target_max);141		fflush(stdout);142		sleep(1);143	}144 145	bpf_link__destroy(link);146	UEI_REPORT(skel, uei);147	scx_qmap__destroy(skel);148	/*149	 * scx_qmap implements ops.cpu_on/offline() and doesn't need to restart150	 * on CPU hotplug events.151	 */152	return 0;153}154