yihong0618 和朋友们的频道 头像

消息来源频道

yihong0618 和朋友们的频道

@hyi0618

频道8,612 位成员公开可见0 人在线

yihong0618 和朋友们的频道

成员规模8,612 位成员
在线情况0 人在线
消息总数10,129 条消息
浏览量总数3,286,989 次浏览

在这个频道里搜索消息……

t.me/hyi0618

猫头但丁两年前问过我这个有趣的项目 https://github.com/bytedance/trace-irqoff ,其实我也不会,最近才看懂一点。需要理解的前置知识是 linux 很多操作都是由中断抢占,而内核在执行某些热路径的时候又会临时关闭中断(local_bh_disable 关闭软中断,local_irq_save 关闭硬中断)。如果有某些进程关闭中断时间过长(100ms),这个 cpu 队列里的 skb 就会阻塞 100ms。
所以这个项目用来 trace 中断关闭过长的进程和栈。
然而在上述的软硬中断关闭函数处插桩性能影响极大,项目作者 宋牧春 就想到在内核直接起一个 hrtimer 和 timer 采样,前者由硬中断驱动后者由软中断驱动。假如 hrtimer 设置的时长是 10ms,正常来说每 10ms 执行一次回调;但这期间如果 cpu 关闭了 20ms 硬中断,那回调会被推迟到 10+20=30ms,我们对比时间戳就知道这期间发生了长时间中断关闭。再仔细分析代码发现 hrtimer 延迟回调的时候一定就在关闭中断的栈,那直接做栈回溯就能抓到中断长时间关闭的始作俑者了。
这个项目最近被字节归档了,我发邮件请教宋牧春归档原因,说只是公司开源政策,并非技术路线问题。那就好办,原项目是 kernel module,我就想着怎么 bpf 化,但是我有没时间了(每天最多工作5h,其他时间忙着玩😀),所以我看看有没有勇士愿意自告奋勇来做这件大好事(其实挺好玩的)。注意项目协议是 GPL-2.0。
思路是用 tc_run 触发 bpf_timer,这是由软中断驱动的;用 perf_event_open(type=PERF_TYPE_SOFTWARE, config=PERF_COUNT_SW_CPU_CLOCK) 触发硬中断驱动的 timer。要仔细把 bpf_timer 和 perf_event timer 绑在每一个 cpu 上,使用 percpu_array 保证多核数据安全。在 bpf_timer 里栈回溯是个挑战,但是 Leon Hwang 之前的工作可以解决这个问题[1],注意到可以 r10 就是 fp,手写汇编硬抠 r10 然后就可以 fp = *fp 回溯了。其他逻辑直接硬抄原项目,记得在 README 里指向 bytedance/trace-irqoff。
我挺喜欢这个项目的,甚至觉得有机会贡献给 perf 做一个新的子命令 perf irq
[1] https://t.me/eBPFTalker/511