bpf/bcc сообщает об ошибке при попытке доступа к `struct rq`

Это моя программа 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 <linux/sched.h>. Однако он распознает struct task_struct. Эти две структуры находятся в одном головном файле.

Версия ядра: 4.4.0-141-универсальная на Ubuntu 16.04


person Chen Wei    schedule 08.02.2019    source источник


Ответы (1)


struct rq на самом деле не является частью заголовков ядра, так как вы можете см. на Bootlin.

Вы также можете:

  • получить смещение на rq->cpu из указателя rq и жестко закодировать его в вашей программе BPF, но я бы не рекомендовал это делать;
  • или найти другой способ получить номер процессора, возможно, через prev или текущую задачу (например, prev->cpu).
person pchaigno    schedule 08.02.2019
comment
привет, можно подробнее? Я вижу, что и task_stuct, и rq определены в одном и том же файле (include/linux/sched.h). Я точно смогу получить номер процессора к prev. - person Chen Wei; 08.02.2019
comment
Извините, ссылка в моем ответе была неверной; Я починил это. rq определяется в исходниках ядра (kernel/sched/sched.h< /a>), но не в заголовках ядра (include/linux/sched.h). Это два разных файла. - person pchaigno; 08.02.2019
comment
Спасибо, я понял! Это действительно полезно - person Chen Wei; 09.02.2019
comment
Я также заметил, что он отлично работает, если это 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. - person Chen Wei; 09.02.2019
comment
Я пробовал предыдущий процессор. Похоже, это не работает. - person Chen Wei; 09.02.2019
comment
Я думаю, это связано с моей версией ядра 4.4.0. Я обновлю свое ядро. Спасибо! - person Chen Wei; 09.02.2019
comment
Вы хотите, чтобы я что-то изменил, чтобы принять мой ответ? Что за сообщение об ошибке с prev-›cpu? - person pchaigno; 09.02.2019