您好,登录后才能下订单哦!
这篇文章跟大家分析一下“如何在Linux内核中运行WebAssembly”。内容详细易懂,对“如何在Linux内核中运行WebAssembly”感兴趣的朋友可以跟着小编的思路慢慢深入来阅读一下,希望阅读后能够对大家有所帮助。下面跟着小编一起深入学习“如何在Linux内核中运行WebAssembly”的知识吧。
过去的几个月间,我们尝试了各种方法来给 Wasmer WebAssembly 运行环境提速。这些方法包括缓存编译后的代码、实现不同等级的编译后端(Singlepass/Cranelift/LLVM)等,也都取得了不错的效果。
这些优化性能的尝试使我们开始考虑一个更加“基础”的问题:基于 VM(虚拟机)的程序与原生程序相比,有哪些优势?我们是否可以让 WASM 运行得比原生代码更快?
下面将介绍我们在 Linux 内核中实现的 WebAssembly 安全运行环境。我们在 Linux 内核中成功运行了一个 TCP Echo 服务端程序,并取得了相对原生代码 10% 的性能提升。
背景
“第二个操作系统“
许多语言和运行环境,包括 WebAssembly(支持 WASI 的实现)和 JavaScript (Node.js 和浏览器)等,都在尝试于真实的操作系统之上构建第二个沙箱化的“操作系统”。然而,这多出来的一层会带来不小的性能损耗。
如上图所示,在这样的传统架构中,来自 VM 上应用的系统服务请求(系统调用),在到达内核前,需要经过两层边界。
这两层边界的性能损耗很大。一个普通的函数调用所需时间一般小于 5 ns,然而一次来源于 VM 内部的系统调用可能会消耗上百纳秒。
Cervus 的后继者
我大约一年之前写过另一个内核中的 WebAssembly “用户模式”子系统 - Cervus 。那时候 WASI 和“生产级别”的 WebAssembly 运行时都还不存在,但 Cervus 项目已经证明这个想法是可行且有巨大潜力的。
现在 WebAssembly 生态正在快速成长,是时候做一个完整的、面向真实应用的内核模式 WebAssembly 运行环境了。
为什么要在内核中运行 WebAssembly ?
主要原因是性能和灵活性。
WASM 是由虚拟机保护的虚拟指令集。我们不需要依靠外部的软件/硬件保护来确保安全性。
在内核中运行 WASM 避免了这些外部保护引入的性能损耗,如系统调用(上下文切换)、用户态/内核态数据复制等。
同时,有了对底层的控制,我们可以实现很多在用户模式中低效或难以实现的特性,例如直接访问硬件、处理密集的内核事件(如网络包过滤)等。
安全性
在内核模式运行用户代码是件危险的事情。虽然我们用了很多技巧来保护系统免受恶意代码的攻击,我们仍然建议短期之内,在我们没有完整 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
(在 kernel-wasm 上运行的 cowsay )
关于如何在Linux内核中运行WebAssembly就分享到这里啦,希望上述内容能够让大家有所提升。如果想要学习更多知识,请大家多多留意小编的更新。谢谢大家关注一下亿速云网站!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。