使用eBPF进行嘈杂邻居检测
The sched_wakeup
and sched_wakeup_new
hooks are invoked when a process changes state from 'sleeping' to 'runnable.' They let us identify when a process is ready to run and is waiting for CPU time. During this event, we generate a timestamp and store it in an eBPF hash map using the process ID as the key.
sched_wakeup
和 sched_wakeup_new
钩子在进程从 '睡眠' 状态变为 '可运行' 状态时被调用。它们让我们能够识别出进程何时准备好运行并等待 CPU 时间。在此事件中,我们生成一个时间戳,并将其存储在一个 eBPF 哈希映射中,使用进程 ID 作为键。
struct { __uint(type, BPF_MAP_TYPE_HASH); __uint(max_entries, MAX_TASK_ENTRIES);
struct { __uint(type, BPF_MAP_TYPE_HASH); __uint(max_entries, MAX_TASK_ENTRIES);
__uint(key_size, sizeof(u32));
__uint(key_size, sizeof(u32));
__uint(value_size, sizeof(u64));
} runq_enqueued SEC(".maps");
__uint(value_size, sizeof(u64));
} runq_enqueued SEC(".maps");
SEC("tp_btf/sched_wakeup")
SEC("tp_btf/sched_wakeup")
int tp_sched_wakeup(u64 *ctx){
int tp_sched_wakeup(u64 *ctx){
struct task_struct *task = (void *)ctx[0];
struct task_struct *task = (void *)ctx[0];
u32 pid = task->pid; u64 ts = bpf_ktime_get_ns(); bpf_map_update_elem(&runq_enqueued, &pid, &ts, BPF_NOEXIST);
u32 pid = task->pid; u64 ts = bpf_ktime_get_ns(); bpf_map_update_elem(&runq_enqueued, &pid, &ts, BPF_NOEXIST);
return 0;
return 0;
}
}
Conversely, the sched_switch
hook is triggered when the CPU switches between processes. This hook provides pointers to the process currently utilizing the CPU and the process about to take over. We use the upcoming task's process ID (PID) to fetch the timestamp from the eBPF map. This timestamp represents when the process entered the queue, which we had previously stored. We then calculate the run queue latency by simply subtracting the timestamps.
相反,当CPU在进程之间切换时,将触发sched_switch
钩子。该钩子提供了指向当前正在使用CPU的进程和即将接管的进程的指针。我们使用即将到来的任务的进程ID(PID)从eBPF映射中获取时间戳。该时间戳表示进程进入队列的时间,我们之前存储过。然后,我们通过简单地相减时间戳来计算运行队列的延迟。
SEC("tp_btf/sched_switch")
int tp_sched_switch(u64 *ctx){
SEC("tp_btf/sched_switch")
int tp_sched_switch(u64 *ctx){
struct task_struct *prev = (struct task_struct *)ctx[1];
struct task_struct *prev = (struct ...