blob: de99823663bf64a2c0aafc732c6e8ffbe603716f [file] [log] [blame]
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2020 Wenbo Zhang
#include <vmlinux.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_core_read.h>
#include <bpf/bpf_tracing.h>
#include "runqlen.h"
const volatile bool targ_per_cpu = false;
const volatile bool targ_host = false;
struct hist hists[MAX_CPU_NR] = {};
SEC("perf_event")
int do_sample(struct bpf_perf_event_data *ctx)
{
struct task_struct *task;
struct hist *hist;
u64 slot, cpu = 0;
task = (void*)bpf_get_current_task();
if (targ_host)
slot = BPF_CORE_READ(task, se.cfs_rq, rq, nr_running);
else
slot = BPF_CORE_READ(task, se.cfs_rq, nr_running);
/*
* Calculate run queue length by subtracting the currently running task,
* if present. len 0 == idle, len 1 == one running task.
*/
if (slot > 0)
slot--;
if (targ_per_cpu) {
cpu = bpf_get_smp_processor_id();
/*
* When the program is started, the user space will immediately
* exit when it detects this situation, here just to pass the
* verifier's check.
*/
if (cpu >= MAX_CPU_NR)
return 0;
}
hist = &hists[cpu];
if (slot >= MAX_SLOTS)
slot = MAX_SLOTS - 1;
if (targ_per_cpu)
hist->slots[slot]++;
else
__sync_fetch_and_add(&hist->slots[slot], 1);
return 0;
}
char LICENSE[] SEC("license") = "GPL";