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 11 struct hist hists[MAX_CPU_NR] = {}; 12 13 SEC("perf_event") do_sample(struct bpf_perf_event_data * ctx)14int do_sample(struct bpf_perf_event_data *ctx) 15 { 16 struct task_struct *task; 17 struct hist *hist; 18 u64 slot, cpu = 0; 19 20 task = (void*)bpf_get_current_task(); 21 slot = BPF_CORE_READ(task, se.cfs_rq, nr_running); 22 /* 23 * Calculate run queue length by subtracting the currently running task, 24 * if present. len 0 == idle, len 1 == one running task. 25 */ 26 if (slot > 0) 27 slot--; 28 if (targ_per_cpu) { 29 cpu = bpf_get_smp_processor_id(); 30 /* 31 * When the program is started, the user space will immediately 32 * exit when it detects this situation, here just to pass the 33 * verifier's check. 34 */ 35 if (cpu >= MAX_CPU_NR) 36 return 0; 37 } 38 hist = &hists[cpu]; 39 if (slot >= MAX_SLOTS) 40 slot = MAX_SLOTS - 1; 41 if (targ_per_cpu) 42 hist->slots[slot]++; 43 else 44 __sync_fetch_and_add(&hist->slots[slot], 1); 45 return 0; 46 } 47 48 char LICENSE[] SEC("license") = "GPL"; 49