1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2020 Wenbo Zhang
3 #include <vmlinux.h>
4 #include <bpf/bpf_helpers.h>
5 #include <bpf/bpf_core_read.h>
6 #include <bpf/bpf_tracing.h>
7 #include "runqlen.h"
8
9 const volatile bool targ_per_cpu = false;
10 const volatile bool targ_host = false;
11
12 struct hist hists[MAX_CPU_NR] = {};
13
14 SEC("perf_event")
do_sample(struct bpf_perf_event_data * ctx)15 int do_sample(struct bpf_perf_event_data *ctx)
16 {
17 struct task_struct *task;
18 struct hist *hist;
19 u64 slot, cpu = 0;
20
21 task = (void*)bpf_get_current_task();
22 if (targ_host)
23 slot = BPF_CORE_READ(task, se.cfs_rq, rq, nr_running);
24 else
25 slot = BPF_CORE_READ(task, se.cfs_rq, nr_running);
26 /*
27 * Calculate run queue length by subtracting the currently running task,
28 * if present. len 0 == idle, len 1 == one running task.
29 */
30 if (slot > 0)
31 slot--;
32 if (targ_per_cpu) {
33 cpu = bpf_get_smp_processor_id();
34 /*
35 * When the program is started, the user space will immediately
36 * exit when it detects this situation, here just to pass the
37 * verifier's check.
38 */
39 if (cpu >= MAX_CPU_NR)
40 return 0;
41 }
42 hist = &hists[cpu];
43 if (slot >= MAX_SLOTS)
44 slot = MAX_SLOTS - 1;
45 if (targ_per_cpu)
46 hist->slots[slot]++;
47 else
48 __sync_fetch_and_add(&hist->slots[slot], 1);
49 return 0;
50 }
51
52 char LICENSE[] SEC("license") = "GPL";
53