【问题标题】:bpf/bcc reports error when trying to access `struct rq`尝试访问“struct rq”时,bpf/bcc 报告错误
【发布时间】:2019-07-02 06:32:42
【问题描述】:

这是我的 bpf 程序,用于分析内核函数 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;
};

报错如下:

    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:

我的问题是为什么 bpf 无法识别 struct rq,因为我已经包含了 # include &lt;linux/sched.h&gt;。但是,它确实可以识别struct task_struct。这两个结构在同一个头文件中。

内核版本:ubuntu 16.04 上的 4.4.0-141-generic

【问题讨论】:

    标签: linux kernel bpf ebpf bcc-bpf


    【解决方案1】:

    struct rq 实际上不是内核头文件的一部分,你可以see on Bootlin

    您可以:

    • rq 指针中检索到rq-&gt;cpu 的偏移量并将其硬编码到您的BPF 程序中,但我不推荐这样做;
    • 或找到其他方法来检索 CPU 编号,可能通过 prev 或当前任务(例如,prev-&gt;cpu)。

    【讨论】:

    • 嗨,您能详细说明一下吗?我看到task_stuctrq 都定义在同一个文件(include/linux/sched.h)中。我绝对可以通过prev检索cpu号。
    • 对不起,我的答案中的链接不正确;我修好了它。 rq 在内核源代码 (kernel/sched/sched.h) 中定义,但不在内核头文件 (include/linux/sched.h) 中定义。这是两个不同的文件。
    • 谢谢,我明白了!真的很有帮助
    • 我还注意到,如果它是int cpu_id = task_cpu(prev),它可以正常工作。但是添加时会报如下错误:if (cpu_id != 0) return;bpf: Failed to load program: Permission denied 0: (bf) r6 = r1 1: (79) r7 = *(u64 *)(r6 +104) 2: (79) r1 = *(u64 *)(r7 +8) R7 invalid mem access 'inv' HINT: The invalid mem access 'inv' error can happen if you try to dereference memory without first using bpf_probe_read() to copy it to the BPF stack. Sometimes the bpf_probe_read is automatic by the bcc rewriter, other times you'll need to be explicit.
    • 我已经尝试过prev->cpu。好像不行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多