如何在Linux内核中运行WebAssembly-成都快上网建站

如何在Linux内核中运行WebAssembly

这篇文章跟大家分析一下“如何在Linux内核中运行WebAssembly”。内容详细易懂,对“如何在Linux内核中运行WebAssembly”感兴趣的朋友可以跟着小编的思路慢慢深入来阅读一下,希望阅读后能够对大家有所帮助。下面跟着小编一起深入学习“如何在Linux内核中运行WebAssembly”的知识吧。

让客户满意是我们工作的目标,不断超越客户的期望值来自于我们对这个行业的热爱。我们立志把好的技术通过有效、简单的方式提供给客户,将通过不懈努力成为客户在信息化领域值得信任、有价值的长期合作伙伴,公司提供的服务项目有:域名与空间、虚拟空间、营销软件、网站建设、新林网站维护、网站推广。

过去的几个月间,我们尝试了各种方法来给 Wasmer WebAssembly 运行环境提速。这些方法包括缓存编译后的代码、实现不同等级的编译后端(Singlepass/Cranelift/LLVM)等,也都取得了不错的效果。

这些优化性能的尝试使我们开始考虑一个更加“基础”的问题:基于 VM(虚拟机)的程序与原生程序相比,有哪些优势?我们是否可以让 WASM 运行得比原生代码更快?

下面将介绍我们在 Linux 内核中实现的 WebAssembly 安全运行环境。我们在 Linux 内核中成功运行了一个 TCP Echo 服务端程序,并取得了相对原生代码 10% 的性能提升。

背景

  • “第二个操作系统“

许多语言和运行环境,包括 WebAssembly(支持 WASI 的实现)和 JavaScript (Node.js 和浏览器)等,都在尝试于真实的操作系统之上构建第二个沙箱化的“操作系统”。然而,这多出来的一层会带来不小的性能损耗。

如何在Linux内核中运行WebAssembly

如上图所示,在这样的传统架构中,来自 VM 上应用的系统服务请求(系统调用),在到达内核前,需要经过两层边界。

这两层边界的性能损耗很大。一个普通的函数调用所需时间一般小于 5 ns,然而一次来源于 VM 内部的系统调用可能会消耗上百纳秒。

  • Cervus 的后继者

我大约一年之前写过另一个内核中的 WebAssembly “用户模式”子系统 - Cervus 。那时候 WASI 和“生产级别”的 WebAssembly 运行时都还不存在,但 Cervus 项目已经证明这个想法是可行且有巨大潜力的。

现在 WebAssembly 生态正在快速成长,是时候做一个完整的、面向真实应用的内核模式 WebAssembly 运行环境了。

为什么要在内核中运行 WebAssembly ?

主要原因是性能和灵活性。

WASM 是由虚拟机保护的虚拟指令集。我们不需要依靠外部的软件/硬件保护来确保安全性。

在内核中运行 WASM 避免了这些外部保护引入的性能损耗,如系统调用(上下文切换)、用户态/内核态数据复制等。

如何在Linux内核中运行WebAssembly

同时,有了对底层的控制,我们可以实现很多在用户模式中低效或难以实现的特性,例如直接访问硬件、处理密集的内核事件(如网络包过滤)等。

安全性

在内核模式运行用户代码是件危险的事情。虽然我们用了很多技巧来保护系统免受恶意代码的攻击,我们仍然建议短期之内,在我们没有完整 Review 运行环境代码前,只通过这个模块执行可信的代码。

这里是一些已知的安全风险和我们的应对措施:

  • 栈溢出:在代码生成环节插入边界检查代码

  • 内存访问越界:为每个 WASM 任务分配 6GB 的虚拟地址空间,使越界访问无法表达。

  • 信号无法终止处于内核态的进程:接收到终止信号后,将 WASM 代码页面设置为禁止执行(NX)以强制终止执行。

  • 内核态进程浮点状态丢失:用 kernel_fpu_{begin,end} 与 preempt_notifier 手动保存和恢复浮点状态。

  • 内核不支持 Red Zone :在代码生成器中避免使用之。

例子和性能测试

我们提供了两个例子:echo-server 和 http-server 。它们位于 Wasmer 主仓库的 examples 目录下。

当使用 singlepass 后端编译(无优化直接生成 x86-64 代码),并在本地使用 tcpkali/wrk 测试时,echo-server 比它的用户模式等价实现快约 10% (25210 Mbps / 22820 Mbps) ,http-server 快约 6% (53293 Rps / 50083 Rps) 。

这两个例子使用了 WASI (文件抽象、控制台输出)和我们的异步网络扩展(通过 kernel-net 库)。

可以阅读这两个例子的代码,学习怎样编写在 kernel-wasm 中运行的高性能网络程序。

编译、运行

加载内核模块前,请确保:

  • 你的内核版本大于等于 4.15

  • 你的内核启用了抢占执行(preemption)。尝试在未启用抢占的内核上执行 WASM 用户代码会锁死你的系统。

  • 内核头文件和构建环境已安装

首先,clone 仓库:https://github.com/wasmerio/kernel-wasm

然后在仓库的根目录和 networking 、 wasi 目录下执行 make :

makecd networking && makecd ../wasi && makecd ..

加载模块:

sudo insmod kernel-wasm.kosudo insmod wasi/kwasm-wasi.kosudo insmod networking/kwasm-networking.ko

运行 Wasmer 时选择 singlepass 后端和 kernel 加载器:

sudo wasmer run --backend singlepass --loader kernel the_file.wasm

如何在Linux内核中运行WebAssembly

(在 kernel-wasm 上运行的 cowsay )

关于如何在Linux内核中运行WebAssembly就分享到这里啦,希望上述内容能够让大家有所提升。如果想要学习更多知识,请大家多多留意小编的更新。谢谢大家关注一下创新互联网站!


名称栏目:如何在Linux内核中运行WebAssembly
分享地址:http://kswjz.com/article/jdhgip.html
扫二维码与项目经理沟通

我们在微信上24小时期待你的声音

解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流