tools/testing/selftests/sched_ext/total_bw.c
Source file repositories/reference/linux-study-clean/tools/testing/selftests/sched_ext/total_bw.c
File Facts
- System
- Linux kernel
- Corpus path
tools/testing/selftests/sched_ext/total_bw.c- Extension
.c- Size
- 11830 bytes
- Lines
- 481
- 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.
- Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
bpf/bpf.herrno.hpthread.hscx/common.hstdio.hstdlib.hstring.hsys/wait.hunistd.hminimal.bpf.skel.hscx_test.h
Detected Declarations
struct total_bw_ctxfunction run_cpu_stressfunction read_total_bw_valuesfunction read_server_paramfunction write_server_paramfunction read_fair_runtime_allfunction write_fair_runtime_allfunction restore_fair_runtime_allfunction verify_total_bw_consistencyfunction fetch_verify_total_bwfunction setupfunction runfunction cleanup
Annotated Snippet
struct total_bw_ctx {
struct minimal *skel;
long baseline_bw[MAX_CPUS];
int nr_cpus;
};
static void *cpu_stress_thread(void *arg)
{
volatile int i;
time_t end_time = time(NULL) + STRESS_DURATION_SEC;
while (time(NULL) < end_time)
for (i = 0; i < 1000000; i++)
;
return NULL;
}
/*
* The first enqueue on a CPU causes the DL server to start, for that
* reason run stressor threads in the hopes it schedules on all CPUs.
*/
static int run_cpu_stress(int nr_cpus)
{
pthread_t *threads;
int i, ret = 0;
threads = calloc(nr_cpus, sizeof(pthread_t));
if (!threads)
return -ENOMEM;
/* Create threads to run on each CPU */
for (i = 0; i < nr_cpus; i++) {
if (pthread_create(&threads[i], NULL, cpu_stress_thread, NULL)) {
ret = -errno;
fprintf(stderr, "Failed to create thread %d: %s\n", i, strerror(-ret));
break;
}
}
/* Wait for all threads to complete */
for (i = 0; i < nr_cpus; i++) {
if (threads[i])
pthread_join(threads[i], NULL);
}
free(threads);
return ret;
}
static int read_total_bw_values(long *bw_values, int max_cpus)
{
FILE *fp;
char line[256];
int cpu_count = 0;
fp = fopen("/sys/kernel/debug/sched/debug", "r");
if (!fp) {
SCX_ERR("Failed to open debug file");
return -1;
}
while (fgets(line, sizeof(line), fp)) {
char *bw_str = strstr(line, "total_bw");
if (bw_str) {
bw_str = strchr(bw_str, ':');
if (bw_str) {
/* Only store up to max_cpus values */
if (cpu_count < max_cpus)
bw_values[cpu_count] = atol(bw_str + 1);
cpu_count++;
}
}
}
fclose(fp);
return cpu_count;
}
/*
* Read a per-CPU dl_server param (runtime or period) from debugfs.
* Returns the value in nanoseconds, or -1 on failure.
*/
static long read_server_param(const char *server, const char *param, int cpu)
{
char path[128];
long value = -1;
FILE *fp;
Annotation
- Immediate include surface: `bpf/bpf.h`, `errno.h`, `pthread.h`, `scx/common.h`, `stdio.h`, `stdlib.h`, `string.h`, `sys/wait.h`.
- Detected declarations: `struct total_bw_ctx`, `function run_cpu_stress`, `function read_total_bw_values`, `function read_server_param`, `function write_server_param`, `function read_fair_runtime_all`, `function write_fair_runtime_all`, `function restore_fair_runtime_all`, `function verify_total_bw_consistency`, `function fetch_verify_total_bw`.
- Atlas domain: Support Tooling And Documentation / tools.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.