仓库源文

.. Kenneth Lee 版权所有 2019-2020

:Authors: Kenneth Lee :Version: 1.0

主线逻辑


今天和人讨论ebpf是否是VM的问题。这个问题很难讨论,所以我先建立一个“主线逻辑”的 概念,以便问题可以顺利讨论下去。

我先问个问题:Linux的中断处理向量是线程吗?

一般来说,当然不是,但你如何解释request_threaded_irq()?

计算机是一个一层层虚拟化的概念,过去运行在真实计算机中的一个软件,它今天可能被 完全运行在一个VM中。所以,你怎么说明什么是操作系统?需要运行在物理计算机上的才 是操作系统吗?或者换个问法,必须放在一个中断处理上下文中的才是中断处理向量吗?

所以,很多时候,我们定义一个东西是什么,我们不聚焦它的外部环境,我们聚焦它自己 认为自己是什么。request_thread_irq()的向量把自己认为是中断处理向量,我们就认为 它是中断处理向量,而不认为它是线程。如果出了问题,我们认为是你模拟环境的问题, 不是我的中断处理向量的问题。这种情况,我把“认为request_threaded_irq创建了一个中 断处理向量”作为“主线逻辑”,而“这个处理向量也可以在线程上下文中执行”是一种“非主 线逻辑”,或者“主线逻辑的加花”。

这本质是一个我们如何认知这个概念空间的发展的问题。因为主线逻辑和加花本身是可以 互相转化的。

我们很早就开始做WarpDrive了,目的是让CPU和加速器有一个共同的地址空间,这样复杂 指令让加速器干,简单指令让CPU干,他们就可以灵活地分布我们的计算算力,让整个系统 的计算效率达到最优。

为了做到统一地址空间,我们需要IOMMU可以分进程设置页表(这个特性叫SVA),但这个 功能Linux主线还没有支持。所以我们不得不在初期以支持SVA为总的设计目标,但同时支 持NOIOMMU和Mode 1(只支持一个进程)两种模式,以证明这种方案是可行的。

在这个东西应用到产品去的时候,产品才不在乎你什么SVA,什么进程呢。老子就是要性能 ,可靠性,市场占有率……既然SVA现在还不能上,那么就全部力量都放在NOIOMMU上了。然 后所有的一线工程师都在让我不要在乎SVA那些限制,这样NOIOMMU的时候性能更高。我死 活不干,我可以为产品投入我9成的工程量,但我不让你关掉我SVA核心竞争力的门——我就 一个质疑:如果我让NOIOMMU占了上风,我何必做WarpDrive?UIO不就有了所有的功能了吗 ?你离开了你的根本,辛辛苦苦建立的规模,马上会被人抄掉后路。

你看,这里SVA是我们的主线逻辑,NOIOMMU是加花,我们在乎主线逻辑,核心是在乎我们 最终变大的时候会成为什么。离开了根本,你就没有未来。如果request_threaded_irq变 成了线程,那么它的独特价值是什么?

说起来,也可以说这其实就是软件领域的“主要矛盾”,和“矛盾的主要方面”:)

好了,回到ebpf这个问题。把C翻译成ebpf汇编,这是编译器的功能,这不是ebpf的本质。 这是加花。定义一种ebpf的语法,这是对于硬件功能的抽象,这和ebpf的功能无关,而跟 你做的硬件有关。它也没有任何办法抽象所有硬件的公共行为,这条路怎么走都是加花。 如果它要做一种脚本到内核中,Python,LUA,啥都能提供一样的功能,有个VM在上面,安 全性总能保证(当然,这个失去了CPU的Privilege边界的保护,实际上风险是提高的), 但这没有性能。

所以ebpf/bpf的“主线逻辑”是什么?它是:让你插入一段代码到内核中,这段代码性能必 须很高(因为我们的需求是把它插入到关键处理流程中),同时它不能引入安全问题。

所以ebpf/bpf的主线逻辑是:我给你抽象一种可以直接翻译成起来汇编的汇编语法(通常 它是所有其他汇编的子集),我基于这个汇编语法限制了你可以访问的资源范围(比如我 不让你任意寻址),然后编译(基本上是mapping)为本地机器码,最终投入运行的时候, 性能可以得到保证。

这是它的主线,是它可以发展的根本。至于你说你用llvm来抽象高层逻辑,同时支持给网 卡插入固件代码,引入一种bincode的格式,到晚一点再用JIT来展开机器码,这些我认为 都是“加花”,加花的功能是不能用作依托来预判它未来的发展的。