虚拟化网络中的零拷贝

数据包的拷贝是虚拟化网络中最大的性能瓶颈,这些年来,人们也一直在致力于减少内存拷贝甚至消除内存拷贝。根据数据包流向,零拷贝可以分为 Host to VM 的零拷贝和 VM to VM 的零拷贝,前者主要适用于一般的情况,后者更适用于NFV。本文简单枚举下现有的零拷贝的虚拟化网络实现。

1.Host to VM零拷贝

除去之前的文章中讲过的设备透传之外,数据包到达物理网卡在转发之前都必须被存储在主机的数据包缓冲区中,这样要想实现零拷贝,必须允许虚拟机能够直接访问该处的数据包。现有实现有两种方式,一种是采用更决绝的共享内存技术,另一种是在EPT页表层面做一些动态修改。

基于共享内存实现零拷贝

早在09年就有一位博士在自己的毕业设计中提出了一种零拷贝的虚拟化网络IO接口实现,并以Nahanni命名了这种设计的设备和驱动名[1,2],这便是IVSHMEM的前身。但是不幸的是,尽管这位博士在自己论文中以极具攻击性的语气诋毁了社区选择virtio方案的愚蠢行为,但是由于这种共享内存的设计太过大胆,存在严重的安全隐患,因而始终不被内核开发者接纳。

几年以后,这项技术反而在一个新兴的方向被提出,而被更多人知晓。也许没有很多人知道IVSHMEM,但一定知道14年NSDI计算机网络顶级会议上提出的NetVM,他使用的是相同的设计思想,将之应用于NFV领域,并实现了编程所需的基本框架[3]。NetVM代表了虚拟化网络IO中零拷贝共享内存是最好实现,那么这里就用NetVM为例介绍一下这种技术如何发挥作用。

NetVM.png

他实现零拷贝的思路就是:让host的数据包buffer共享给VM,使得VM有能力直接访问主机上属于自己的数据包。另外,还需要共享一对队列,用于VM与host传输数据包过程中的交互,互相指明数据包存在哪了。

这项方式有两点缺点:由于需要VM实现对共享内存内部数据包的直接读取(无须拷贝到自己的buffer),就需要在VM中改写专有驱动,来完成对共享内存这块buffer的内存管理;对于多个VM共享一块内存作为数据包缓冲区,意味着上面的数据包可以随意访问,存在安全性隐患。也正是这两点原因,这项方案难以大规模使用。

但是它在NFV环境下,多VM共享一块内存的设计却是提升性能的关键。因为NFV旨在利用虚拟化的资源(如:VM或者容器)来实现物理设备实现的网络功能,从而构成服务链,也就是说一条服务链上可能有很多个运行不同网络功能的虚拟机,数据包(flow)需要穿过这么多虚拟机,内存拷贝会让性能急剧下降。因此,在NetVM方案下,一个数据包可以同时被一条服务链上所有的VM访问,结合一些NFV并行化的操作,可以大大提高NFV的性能。

下面简要说明一下这种直接host与VM共享内存是如何实现的吧。

设备共享内存.png

答案还是设备模拟,使用设备内存。QEMU是VM主进程,也是负责给VM提供所有的设备模拟的。在启动VM的时候,QEMU给VM虚拟出来一个PCI设备,并将host的buffer作为设备内存注册进设备的数据结构。这样一旦VM需要访问设备的时候,就会被重定向到host的buffer。

page-flipping实现零拷贝

这项技术在十年前,就有人提出并在Xen虚拟化机制上做了实现。最近,也有人把它实现在了QEMU/KVM虚拟化上,并且基于的是vhost-user做改动[4]。

这种方法的设计思想是:VM内存访问是经过EPT页表,将GPA(Guest Physical Address)翻译成HPA(Host Physical Address),既然这样就可以不用共享内存,直接改数据包所在页的EPT页表表项,使得VM访存时被重定向到数据包所在的物理页。

page-flipping.png

这种方式就是“简单粗暴”,需要修改网卡驱动对内存的管理,以及KVM内核代码,允许EPT表项映射关系被动态修改。这也正是其缺陷所在,不论数据包大小,每次数据包传输都需要改EPT表项,而这是一个很昂贵的操作。实验结果表明,它拖累了小包的传输,只有在数据包大小超过1518字节(那也就是只有巨型帧了),这种方式才比数据包拷贝要快。

2.VM to VM零拷贝

其实上面所说的NetVM和IVSHMEM已经实现的VM间零拷贝了,这里就说下vhost-user尚未开源的一些设计。

因为virtio已经被社区接纳并且进入大部分操作系统的内核,因此对基于virtio的各项feature的优化,还是有很多人在做。我这里要说的就是virtio在VM间共享内存的技术vhost-pci。

vhost-pci示意图.png

它的想法非常直接,如果一个VM能够直接从另一个VM中读取数据包而不需要拷贝,那么可以极大加快服务链上的效率。这在实现上非常类似NetVM和IVSHMEM,为需要进行VM to VM传输的VM虚拟一个热插拔设备叫做vhost-pci,设备内存就是另一个VM的内存,在VM中再实现一套驱动,让VM间通信变得类似于vhost-user的前后端操作,就可以实现零拷贝。在github上已经有vhost-pci的实现了:https://github.com/wei-w-wang/vhost-pci,不知道为什么没有推进社区。

关于虚拟机间通信,Intel和开源社区也还有一个更灵活的想法,让每个QEMU进程有“弱交换机”的功能,VM在往外发送数据包的时候由这个“弱交换机”判断是VM间通信还是与外部通信,从而确定走vhost-pci快速通道还是走OVS转发。而这些QEMU“弱交换机”还会和OVS进行交互更新流表项等操作。当初见到这个设计的时候真的佩服设计者的脑洞,但是现在还是停在原型验证阶段,可能里面还有什么巨坑吧。

但是这项快速通路带来了另一个问题——安全问题。考虑到允许一个VM直接访问另一个VM内存,这是一项极其危险的操作,如果能有一个“protected view”去做这项事情就好了。

为了实现这项安全地访问外部资源(敏感资源)的技术,Intel直接在硬件层面上下功夫了,并为此申请了全球专利。这项技术叫做EPTP switching。这项技术允许一个VM拥有多个EPT页表,通过写寄存器,实现EPT页表之间的切换。

科普一下,它不仅可以用于安全地访问外部资源上,由于它的开销极低,一些虚拟机内存监视器也使用了该方法。去年“熔断”和“幽灵”两大漏洞让Linux社区为此重新设计了页表,提出的KPTI让性能降低很多;因此有人认为在云上,虚拟机可以不用打这么大开销的补丁,可以直接利用多项EPT页表技术来实现对VM内存的监视[5]。

EPT页表切换示意图.png

回到vhost-pci策略上来,我们为一个VM建立两个EPT页表:一个是default页表,另一个是包含别的VM内存的EPT页表。可以调用VMFUNC中的EPTP switching在这两种页表之间切换。

数据包转发流程示意图.png

在这种机制下的数据包传输就变成上图这样:在进入发送函数时,目的VM的内存是不可见的;先调用VMFUNC切换到protected view,目的VM的内存可见,进行数据包send;发送完以后,再调用VMFUNC切换default EPT页表,目的VM的内存又变得不可见了。

这样就实现了既安全又高效的VM间数据传输,可惜这套方案已经被专利保护,再没有发挥余地了。

引用:
[1] Macdonell A C. Shared-memory optimizations for virtual machines[J]. 2011.
[2] MacDonell C. Nahanni, a shared memory interface for kvm[J]. Aug, 2010, 10: 19.
[3] Hwang J, Ramakrishnan K K, Wood T. NetVM: High Performance and Flexible Networking Using Virtualization on Commodity Platforms[C]//11th {USENIX} Symposium on Networked Systems Design and Implementation ({NSDI} 14). 2014: 445-458.
[4] Wang D, Hua B, Lu L, et al. Zcopy-vhost: Eliminating Packet Copying in Virtual Network I/O[C]//2017 IEEE 42nd Conference on Local Computer Networks (LCN). IEEE, 2017: 632-639.
[5] Hua Z, Du D, Xia Y, et al. {EPTI}: Efficient Defence against Meltdown Attack for Unpatched VMs[C]//2018 {USENIX} Annual Technical Conference ({USENIX}{ATC} 18). 2018: 255-266.

vhost-pci中图 来源于 “Extending KVM Models Toward High-Performance NFV; Jun Nakajima, James Tsai, Mesut Ergin, Yang Zhang, and Wei Wang; Intel”

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容