tools/sched_ext/scx_pair.c

Source file repositories/reference/linux-study-clean/tools/sched_ext/scx_pair.c

File Facts

System
Linux kernel
Corpus path
tools/sched_ext/scx_pair.c
Extension
.c
Size
5519 bytes
Lines
197
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

switch (opt) {
		case 'S':
			stride = strtoul(optarg, NULL, 0);
			break;
		case 'v':
			verbose = true;
			break;
		default:
			fprintf(stderr, help_fmt, basename(argv[0]));
			return opt != 'h';
		}
	}

	/* Stride must be positive to pair distinct CPUs. */
	if (stride <= 0) {
		fprintf(stderr, "Invalid stride %d, must be positive\n", stride);
		scx_pair__destroy(skel);
		return -1;
	}

	if (skel->rodata->nr_cpu_ids & 1) {
		fprintf(stderr, "scx_pair requires an even CPU count, got %u\n",
			skel->rodata->nr_cpu_ids);
		scx_pair__destroy(skel);
		return -1;
	}

	bpf_map__set_max_entries(skel->maps.pair_ctx, skel->rodata->nr_cpu_ids / 2);

	/* Resize arrays so their element count is equal to cpu count. */
	RESIZE_ARRAY(skel, rodata, pair_cpu, skel->rodata->nr_cpu_ids);
	RESIZE_ARRAY(skel, rodata, pair_id, skel->rodata->nr_cpu_ids);
	RESIZE_ARRAY(skel, rodata, in_pair_idx, skel->rodata->nr_cpu_ids);

	for (i = 0; i < skel->rodata->nr_cpu_ids; i++)
		skel->rodata_pair_cpu->pair_cpu[i] = -1;

	printf("Pairs: ");
	for (i = 0; i < skel->rodata->nr_cpu_ids; i++) {
		int j = (i + stride) % skel->rodata->nr_cpu_ids;

		if (skel->rodata_pair_cpu->pair_cpu[i] >= 0)
			continue;

		SCX_BUG_ON(i == j,
			   "Invalid stride %d - CPU%d wants to be its own pair",
			   stride, i);

		SCX_BUG_ON(skel->rodata_pair_cpu->pair_cpu[j] >= 0,
			   "Invalid stride %d - three CPUs (%d, %d, %d) want to be a pair",
			   stride, i, j, skel->rodata_pair_cpu->pair_cpu[j]);

		skel->rodata_pair_cpu->pair_cpu[i] = j;
		skel->rodata_pair_cpu->pair_cpu[j] = i;
		skel->rodata_pair_id->pair_id[i] = pair_id;
		skel->rodata_pair_id->pair_id[j] = pair_id;
		skel->rodata_in_pair_idx->in_pair_idx[i] = 0;
		skel->rodata_in_pair_idx->in_pair_idx[j] = 1;
		pair_id++;

		printf("[%d, %d] ", i, j);
	}
	printf("\n");

	SCX_OPS_LOAD(skel, pair_ops, scx_pair, uei);

	/*
	 * Populate the cgrp_q_arr map which is an array containing per-cgroup
	 * queues. It'd probably be better to do this from BPF but there are too
	 * many to initialize statically and there's no way to dynamically
	 * populate from BPF.
	 */
	outer_fd = bpf_map__fd(skel->maps.cgrp_q_arr);
	SCX_BUG_ON(outer_fd < 0, "Failed to get outer_fd: %d", outer_fd);

	printf("Initializing");
        for (i = 0; i < MAX_CGRPS; i++) {
		__s32 inner_fd;

		if (exit_req)
			break;

		inner_fd = bpf_map_create(BPF_MAP_TYPE_QUEUE, NULL, 0,
					  sizeof(__u32), MAX_QUEUED, NULL);
		SCX_BUG_ON(inner_fd < 0, "Failed to get inner_fd: %d",
			   inner_fd);
		SCX_BUG_ON(bpf_map_update_elem(outer_fd, &i, &inner_fd, BPF_ANY),
			   "Failed to set inner map");
		close(inner_fd);

Annotation

Implementation Notes