This is my bpf program to profile a kernel function pick_next_task_fiar
.
#include <uapi/linux/ptrace.h> #include <linux/sched.h> #include <linux/nsproxy.h> #include <linux/pid_namespace.h> struct rq; // forward declaration struct val_t { pid_t pid; u64 vruntime; int type; // Note, 0 for previous task, 1 for next task. }; BPF_PERF_OUTPUT(events); int kprobe_pick_next_fair(struct pt_regs *ctx, struct rq *rq, struct task_struct *prev) { int cpu = rq->cpu; struct val_t data = {}; data.pid = prev->pid; data.vruntime = prev->se.vruntime; data.type = 0; events.perf_submit(ctx, &data, sizeof(data)); return 0; };
It reports error as follow:
int cpu = rq->cpu; ~~^ /virtual/main.c:8:8: note: forward declaration of 'struct rq' struct rq; // forward declaration ^ 1 error generated. Traceback (most recent call last): File "picknextfair__back.py", line 73, in <module> b = BPF(text=bpf_text) File "/usr/lib/python2.7/dist-packages/bcc/__init__.py", line 297, in __init__ raise Exception("Failed to compile BPF text:n%s" % text) Exception: Failed to compile BPF text:
My question why the bpf can not recognise the struct rq
since I have already included the # include <linux/sched.h>
. However, it does recognise the struct task_struct
. These two structs are in the same head file.
Kernel version: 4.4.0-141-generic on ubuntu 16.04
Advertisement
Answer
struct rq
is actually not part of the kernel headers, as you can see on Bootlin.
You can either:
- retrieve the offset to
rq->cpu
from therq
pointer and hardcode it in your BPF program, but I wouldn’t recommend it; - or find some other way to retrieve the cpu number, maybe through
prev
or the current task (e.g.,prev->cpu
).