LWN: Facebook使用BPF的情况以及其他

640
点击上方蓝色“ Linux News搬运工”关注我们~

BPF at Facebook (and beyond)

By Jonathan Corbet


Kernel Recipes

Facebook内部做了很多工作来完善kernel内部的BPF虚拟机以及相关的user-space支持代码,这方面大家都很了解了,不过还很少有人知道Facebook内部是怎么使用BPF的。在Kernel Recipes 2019会议上,BPF开发者Alexei Starovoitov给出了一些介绍。不过他本人也承认并不了解他们内部绝大多数的BPF program具体是做什么。与此同时他也总结了一下最近BPF相关的开发工作以及未来规划。

640

Kernels at Facebook

Facebook也有一个upstream-first的原则,并且推崇到了极致。公司希望一个out-of-tree(指mainline kernel未包含的代码)的patch都不要有。Facebook的所有工作都希望能以最快速度推到upstream。公司也会尽快进行kernel升级,通常在几天的时间内就能升级到一个新版本的kernel上去,其实还可以更快的,不过要让数千台机器都reboot还是会花费不少时间。目前Facebook内部用的最多的kernel版本是4.16,此外还有一些机器运行4.11,有一些是5.2。

他特别指出上面列的都不是long-term-support kernel,因为Facebook不打算在某个kernel版本待太长时间,因此他们并不太关心long-term support。实际上服务器通常都会升到最新的可用版本上。不过内部来说,针对主要在用的kernel版本,Facebook的kernel团队会根据大家需求来把更加新的版本kernel里的patch给backport回来。这就给某些应用程序带来了挑战,尤其是基于BPF的那些应用程序。

kernel开发的第一条原则就是“don't break user space”(严禁让user space受影响),如果有哪些功能会导致user-space程序出错的,慢慢的也都变成了kernel ABI的一部分(意思是说需要一直保持这个行为确保向后兼容)。这个原则也包括性能不能变差。性能问题是很容易就出现新的,所以Facebook需要有一个团队来debug这类问题,后来发现BPF通常都是导致这类性能问题的罪魁祸首。

Starovoitov问在场的听众,请大家猜一猜,在各位的laptop上,运行了多少个BPF program?然后试着用下列命令自己来确认一下吧:

   ls -la /proc/*/fd | grep bpf-prog | wc -l

在LWN编辑本人的系统上看到有6个,全部都是systemd所调用的。Starovoitov对Facebook这边的情况很惊讶,因为他看到每台server都有40个BPF program正在运行,并且其实还有100来个等着按需加载。公司里有很多团队都在开发、部署BPF program,而kernel团队甚至都没有完全了解这些BPF program都是干什么的。这些BPF program开发模式也各不相同,有的是利用kprobe,有的是利用tracepoint和network scheduling-class helper,还有10%是其他类型。

他用几个例子来说明为什么大家认为性能问题都(至少是表面上)来自BPF:

  • Facebook有一个抓包的daemon程序,是利用network scheduling-class BPF program来实现的。它会时不时吐出一个network packet供检查。在新的kernel版本上,运行这个daemon程序会导致系统性能下降1%。后来发现这个daemon同时还利用了另一个kprobe位置加载了另一个BPF program做了一件别的什么事。而在新kernel版本里,这个kprobe位置已经被删除了,因此daemon误以为BPF整个都出了问题,因此它就退回到以前的旧方案去抓包了,所以更慢。kprobe并不是stable ABI,会随着kernel版本而变化。kernel开发者这边每次改动一个function kprobe的用法的时候,通常都会导致其他人碰到问题并且花时间去调查。

  • Facebook的最重要的性能分析工具是一个profiling daemon,也是使用了BPF program来基于scheduler等模块的tracepoint和kprobe采集信息。在新版本的kernel上,这个工具又会导致2%的性能下降,表现形式是软件中断处理时间变长了。最后发现在5.2 kernel里,每次设置kprobe的时候都会导致当前这个text section代码段进行一次remap,从2MB的huge page换成普通的4KB page,因此导致了TLB miss的比例变高,降低了性能。

  • Facebook还有一个安全监控daemon,会在3个kprobe位置以及1个kretprobe的位置加载BPF program。这个daemon的优先级很低,大概每几秒钟醒来一次,通常只消耗CPU的0.01%。大家发现在一些高优先级的数据库应用程序运行时,会偶发一些高延迟现象。在debug一段时间之后看到数据库的memcpy()调用有时候会卡住一段时间,甚至长达1/4秒,而此时这个daemon就正在读对应的/proc/pid/environ文件。深入调查进去之后发现,这个daemon在读/proc下面的文件时会需要先获取mmap_sem锁,然后它有可能被调度出去挺长时间,导致主要进程的page fault被block了。这里的root cause是一个很常见的优先级反转问题,只要把这个安全监控daemon的优先级提高就能解决问题了。

上述这些问题——尤其是最后一个——可以看出,调查这些BPF相关的性能衰退问题,最好的工具就是BPF。

Current and future BPF improvements

还有一类问题,是由于BPF program的编译方式所引起的。user-space应用程序会包含一个或者多个BPF program等着加载进kernel。这些程序都是用C语言写的,编译成BPF虚拟机的指令流。这个编译动作是在target system上做的。为了确保编译的结果永远都是一致的,在应用程序里其实嵌入了某一个版本的LLVM编译器。这样就导致这个应用程序变大了,编译时的开销也可能会导致target system上的主要工作进程收到影响。编译过程也很有可能会耗不少时间,因为它的优先级不高,我们经常看到花费了几分钟才编译了一个100行的BPF程序。有时候target system上的头文件里面可能还缺少某些kernel data structure,导致编译会出错。这种问题挺讨厌的。

解决方案可能还是要靠5.4 kernel里会合入的“compile once, run everywhere”功能。具体来说就是用专门为此创建出来的BPF type format (BTF)数据来描述kernel data structure结构。只要kernel提供了BTF数据,就不再需要依赖kernel header了,bpftool工具只要提取出BTF数据然后在target system上创建一个"monster header file"就好。并且加了一个LLVM built-in函数,目的是能预留BPF program可能会用到的结构里的offset,这些offset偏移会在运行时“relocate”(重定位)来保证吻合target kernel上的相应结构内部的位置。

他说2019年还有其他一些有趣的项目进展也不错。首先5.3 kernel已经让verifier支持了bounded loops(有限次数的循环),这个工作是过去两年持续推进才完成的。BPF program现在也可以利用spinlock来管理一些并发行为,而verifier会确保这些program不会死锁。新增了功能来把没用到的代码去除掉,并且也支持了scaler precision tracking。

Starovoitov提到人们经常抱怨BPF verifier很难用,不过其实他认为BPF verifier比起LLVM编译器来说已经要聪明得多了,并且这个优势让我们得到了好几个好处,包括可以确认BPF program是否可以安全加载到kernel里,并且verifier在dead-code elimination(无用代码删除)的时候做得比LLVM更好。

将来verifier会更多利用BTF数据,从而会变得更加好用。例如,每一种program类型都有自己的代码模板函数来提供对传给BPF program的上下文对象进行访问的能力,并且检查这些对象。这样kernel变得更大,也更容易有bug。利用BTF,这些函数就不再需要了,verifier可以直接利用BTF数据来直接检查program了。他估计这样就可以删除kernel里的大约4000行代码。

最后他总结说BPF开发是“完全由使用场景驱动的”。要想知道它今后是什么样子,就需要不断告诉大家有哪些新功能会对大家有用。当然,要是能实现新的BPF扩展功能并且贡献给社区那就更加好了。

[Your editor thanks the Linux Foundation, LWN's travel sponsor, for supporting his travel to this event.]

全文完

LWN文章遵循CC BY-SA 4.0许可协议。

极度欢迎将文章分享到朋友圈 
热烈欢迎转载以及基于现有协议修改再创作~

长按下面二维码关注:Linux News搬运工,希望每周的深度文章以及开源社区的各种新近言论,能够让大家满意~

640?wx_fmt=jpeg

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值