SRIOV:智能网卡就靠它了!

SSDFans 2020-04-01


点击蓝字
关注我们



在DPDK的那一篇中,其实有一个重要的笔误,但是除了一个朋友看到后指出外,基本上没有人说到这个。这个就是DPDK是Kernel-Bypass的,本写成了Kernel-By。


看样子,大家都有深知kernel-bypass对于高速网络的重要性。在云计算的VPC业务主流之前,大部分都预见了kernel的瓶颈。

一个MTU 1500的帧的Time budget [1]

10Gbit/s  =1230.4ns  (812, 774     PPS)

25Gbit/s  =  492.3ns    (2,031,859    PPS)

40Gbit/s  =  307.6ns    (3,251,096    PPS)

100Gbit/s=  123.0ns    (8,127,740    PPS)

同样,对于最小的以太帧84Byte,

10Gbit/s  = 67.2ns  ( 14,880,952 PPS)

以一个主流的Intel的X86 的CPU,3.0G为例:67.2ns 差不多就是201个CPU Cycle。[2]


而linux kernel主要的机制的代价如下:

因此结论也很明确,目前linux 缺省的网络协议最高也只能handle

1-2MPPS的性能,大家需要考虑kernel-bypass。[3]


目前Linux已知的Kernel-ByPass 框架:

  1. DPDK  (Intel/LF)

  2. RDMA/IBVerbs (Mellanox/OFA)

  3. eBPF/XDP  (Vmware/FB/RedHat/Huawei)

  4. netmap (FreeBSD)

  5. PF_RING/DNA (ntop)

  6. OpenOnload (Xilinx)

  7. Maglev (Google)

  8. Snabb  (Deutsche Telekom)

  9. FD.IO/VPP (Cisco)

这里就在回应上一篇ARM同学的话,原来做硬件的网卡厂家只需要照顾自己的Linux驱动,但是现在为了让自己Smart起来,就要支持不同的kernel-bypass的框架,这个的确是伤不起。关键还有一点就是,这样的硬件厂家本来也就不多了。


个人觉得Redhat关于DPDK项目的声明是非常好的例子[4],总结下来如下:

  1.   Redhat的网络总监是从Broadcom过来的,之前参加了很多项目。 包括:upstream and downstream development of Linux kernel networking, DPDK, OVS OVN, NFV, MPTCP, ebpf XDP.

  2. Redhat和DPDK之间的关系只要是使用DPDK进行OVS的packet转发。

  3. 对于DPDK,在新的硬件出现之后,不用等待kernel的驱动upstream,就可以使用新硬件。

  4. Telco 是Redhat主要关注的客户,他们希望使用X86和Redhat的开源软件。

  5. 目前DPDK的贡献者太少了,只有Redhat,Mellanox和Intel。

  6. 最后就是DPDK如何和SmartNIC结合,这个是Redhat和一些硬件厂家一起比较关心的。


对于软件人员来讲,需要通过各种不同的编程框架来实现Kernel-bypass,但是PCIE设备的一个SRIOV能力就可以非常简单的实现了对于host kernel的bypass。

SRIOV的问题也是很明显的:[5]

  • Rigid: Composability issues

  • Control plane is pass through, puts pressure on Hardware resources

  • Parts of the PCIe config space are direct map from Hardware

  • Limited scalability (16 bit)

  • SR-IOV NIC forces switching features into the HW

  • All the Switching Features in the Hardware or nothing

因此,就有了Redhat系列的新思路:

https://www.redhat.com/en/blog/achieving-network-wirespeed-open-standard-manner-introducing-vdpa

https://www.redhat.com/en/blog/how-deep-does-vdpa-rabbit-hole-go

https://www.redhat.com/en/blog/vdpa-hands-proof-pudding


SRIOV隔离VM的流量:



  1.  OVS的kernel和SRIOV

    不使用PF,而是VF上提供多个网络接口给OVS kernel模块。每个VF都有一段kernel 内存空间。

  2. OVS DPDK和SRIOV

    直接使用VF可以bypass kernel空间直接对接用户态的OVS DPDK模块。我们把host用户态的内存映射到每个网卡的VF。

  3. Guest的 SRIOV 

    如上图最右边,我们把Guest的内存空间映射到网卡的VF。在这种设备绑定中,网卡的ring 的layout在物理网卡和Guest之间共享。因为这部分的信息都是私有的,因此Guest上需要制定网卡厂家的驱动。

上面还有一种设备绑定,就是在Guest的用户态通过DPDK访问在Guest中的VF网卡设备。


SRIOV For Mapping NIC to Guest


对于在Guest空间的SRIOV设备,在实现通过memory的映射的机制进行网路报文的快速收发,有两条路径:


  1.  使用Guest 的kernel驱动。使用网卡厂家的驱动,通过直接映射IO memeory,网卡的硬件设备可以直接访问guest kernel的内存。基本上支持SRIOV的厂家都有类似的实现,例如AWS的ENA,Intel的ixgbegbe,以及Mellanox的MLX4/5.

  2. 在Guest上使用DPDK,利用厂家提供的VF的PMD驱动,通过DPDK的内存映射,网卡设备可以访问Guest的用户态内存。



在这个场景中:

  1.  整个数据通路是厂家定义的,并且直接由VF功能来实现。

  2. 对SRIOV,需要在Host的kernel (PF 驱动)以及Guest的用户态(VF-PMD)

  3. Host kernel的驱动和Guest的用户态的VF-PMD不能直接通信。因此PF/VF驱动需要通过其他的接口进行。

  4. 厂家的VF-PMD主要用来配置NIC的VF,而host kernel的PF驱动则负责整个网卡的配置。

这个里面,的确可以实现线速的网络性能,但是因为接口都需要网卡厂家来提供,这样对于整个系统的升级相对比较麻烦。


Virtio Full HW Offloading

这个的确是摆脱厂家驱动的一个办法,把virtio的数据和控制通路都卸载到硬件中,物理网卡通过SRIOV提供VF给Guest。这个设备同样支持virtio ring的layout,在guest和NIC之间建立内存映射。



在Virtio Full Offloading中,在Host kernel甚至不需要驱动,物理网卡是一个支持SRIOV的virtio网卡,VF和PF都是基于virtio协议的实现。


在这个图中,SRIOV带来的控制路径和数据路径bypass可能会对管理带来挑战。同样, 我们可以在Guest的OS 中使用virtio的kernel驱动,而不是PMD。


vDPA  --标准化数据通路

vDPA -虚拟的数据通路加速,它的主要目的是标准化网卡的SRIOV数据通路,让SRIOV的VF可以支持virtio ring的layout,并且在Guest的空间可以使用标准的virtio驱动,而不是厂家的驱动。通过这个抽象,可以在为未来支持类似于scalable IOV的技术。


和上图不同,在SRIOV的VF的控制路径上可以让厂家继续使用自己的驱动(支持vDPA addon),并通过一个标准的vDPA驱动在厂家驱动/virtio之间进行翻译。

在数据路径,基本上和上图的Virtio Full hardware offloading类似。

vDPA的主要好处:


  1.  开放的标准,和virtio一样

  2. 线速性能,和SRIOV一样,没有中间的memory地址翻译。

  3. 可以支持未来的Scaleble IOV

  4. 统一了Guest的网卡驱动。

  5. 可以在两个vDPA的网卡之间做冗余保护。

  6. 支持live migration,因为了vDPA一个控制链路的中间层,因此可以在不同的网卡厂家之间进行live migration。

  7. 在裸金属的场景下,virtio的驱动可以成为一个事实上的标准驱动,和NVMe驱动一样,通过vDPA的框架支持不同厂家的网卡。


对比:

这个里面可能要纠正一点就是,Virtio Full HW offloading对于live migration的支持,这里主要是指在不同的厂家之间进行live migration。



------------------------------------------------------------------------------

Deep Dive


HW Blocks for virtio Full HW offloading

在一般的情况下,厂家的网卡PF创建VF的时候都使用自己专用的ring layout,但是在virtio full HW offloading中使用virtio的 ring layout。

HW Blocks for virtio Full HW offloading

对于Full HW offloading的网卡,都要使用vfio-pci的kernel驱动进行virtio full hw offloading的设备访问,在Host和Guest中都一样。


下面的Full pciture,可以看出来数据通路和控制通路的区别。


来讨论一下网卡如何访问Guest的应用的queue。

  1.  网卡和Guest 之间的内存映射应该先建立,然后才能DMA。

  2. 为了建立DMA的mapping,guest的PMD的驱动使用ioctl命令去配置DMA和vfio。这个时候,iommu主要是映射 GIOVA到GPA

  3. 之后,vIOMMU会把GPA翻译成HVA

  4. Guest这边就建立了GIOVA到HVA的映射

  5. 同样,在host side,VFIO建立了GIOVA到HPA的映射

  6. 网卡开始使用GIOVA,这样它就可以访问到guest application使用的HPA。

  7. 一旦我们设置了guest应用的virtqueue,HW就可以直接去访问它们。


对于控制路径:

  1.  virtio-net-pmd和guest kernel的VFIO通信。

  2. Guest的VFIO和vfio-pci交互

  3. Guest kernel的vfio-pci驱动和QEMU的vfio设备通过虚拟的PCIE bus交互。

  4. QEMU的vfio设备访问host kernel的VFIO (通过ioctl)

  5. Host kernel的VFIO和host kernel的vfio-pci交互。

  6. Host kernel vfio-pci和真正的物理网卡交互。


这个要求数据和控制路径都全部卸载到硬件。这个需要网卡厂家完全在网卡中实现virtio的全部协议,一般是通过一个标准的接口如PCIE。但是,一般来讲,每个厂家肯定有不同的实现机制。


对于live migration,仅仅实现了virtio的协议是不够的,比如dirty pages的tracking,这个需要网卡和QEMU的API之间进行协作。在Virtio的1.1的标准中,并没有这方面的定义。


这里多说一下,对于一个PCIE设备进行live migration, 一般的需要处理的内容如下:

  1. 在Guest中通过ioMMUtracking 脏页内存。

  2. 统一的VF和半虚拟化的驱动。

  3. 处理Guest和Host之间的IO共享内存。

  4. Doorbell以及对应的PCIE寄存器和中断的映射。

因此,如果你可以实现对这些内容的处理和监控,从Guest OS来看,你是不是个Virtio设备并不重要。


vDPA

和前面的Full HW offloading对比,vDPA就是可以使用一个厂家自定义的控制路径,但是在Guest面前又是一个标准的virtio设备。因此就需要一个在网卡私有控制和virtio之间的翻译。


这里就引入了一个新机制,mdev, mediator device可以实现设备的仿真(软件虚拟化)和设备的中介(软件和硬件虚拟化)。它可以在一个物理设备上暴露出多个虚拟设备。mdev最早是用在GPU的虚拟化的场景。Intel增加它对IOMMU的支持。[6]



本质上,vDPA在数据路径还是全部使用HW,但是在控制路径上使用mdev的机制进行设备仿真。

在使用SRIOV中,一个网上的可以配置多个VF,但是每个VF都有自己特定的内存空间(在Guest中),但是VF无法访问host上的mdev的空间,因此目前在使用SRIOV时,控制路径上和mdev相关的操作要经过PF,或者只能是单向的mdev到VF。未来的Scalable IOV会解决这个问题。


至于VFIO的驱动框架,就是用户态对于PCIE设备的支持访问,这个框架可以支持各种设备,比如GPU. 这就意味着Guest上的用户态应用可以支持访问物理设备。


MDEV包含了以下部分:

1.mediated core driver API

2.mediated device API

3. mdev-bus

4. management interface

 


Virtio-Mdev 框架

virtio-mdev框架的主要目的是提供给不同的vDPA网卡厂家一个标准的API来实现他们自己的控制路径。mdev提供的框架可以支持vDPA实现数据和控制路径的分离。数据路径硬化,控制路径在软件实现。

这个驱动可以是用户态基于VFIO,也可以是内核态基于virtio的。在目前这个系列,主要关注基于vfio的用户态驱动,但是在未来也会讨论基于virtio的内核态驱动,比如支持AF_VIRTIO。

这个驱动的实现也比较简单,本质上就是一些列的virtio-mdev的API。主要包含:

.set/get 设备的配置空间

.set/get virtqueue的元数据:vring地址,大小和基地址

.kick一个特定的virtqueue

.为一个特定的virtqueue注册回调中断

.协商功能

.set/get 脏页日志

.启动/重置设备


vhost-mdev 是一个kernel的模块,主要功能是:

  1.  转发用户空间的virtio 命令到virtio mdev的API

  2. 重用VFIO的框架来准备DMA映射和解映射的用户空间请求。


vhost-mdev的主要功能:

.把自己注册成一个新类型的mdev驱动

.对外提供和vhost-net兼容的ioctl接口,用户空间的VFIO驱动可以传递virtio的命令

. 翻译好的virtio命令以virtio mdev API的形式通过mdev bus传递给virtio-mdev设备。

.当一个新的mdev设备创建时,kernel总是厂商去加载驱动

.在加载过程中,vhost-mdev会把virtio mdev设备连接在VFIO的群组,因此DMA请求就可以通过VFIO的文件描述符。


vhost-mdev是连接用户空间驱动(这里是VFIO)和virtio-mdev设备的关键。它为用户空间驱动提供两个文件描述符:

  1.  vhost-mdev FD:从用户空间接受vhost的控制命令

  2. VFIO container FD:用户空间驱动用来设置DMA


Virtio-mdev 驱动可以把自己注册成一个新的mdev设备,暴露一个基于mdev的传输接口给vitio驱动。它作为kernel的virtio驱动和virtio mdev设备的桥梁。因为virtio支持的其他类型传输方式,因此它可以无缝地和virtio-net驱动对接。


virtio-mdev设备本质就是一个mdev设备,它可以使用virtio-mdev驱动,也可以使用vhost-mdev驱动,vDPA主要关注vhost-mdev流程。


如果从mdev-bus的角度看virtio-mdev,它就是一个设备,因为它实现了mdev设备的API。


如果从PCIE BUs的角度看virtio-mdev,它就是一个驱动,因为它主要作用就是发生命令到真正的硬件去。

注意,在本图中,virtio-mdev驱动和virtio-mdev驱动在这里主要表示virtio mdev设备统一的mdev 的API,但是他们并不是vDPA kernel流程的一部分。


vDPA kernel based 实现

我们需要引入一个新的模块vhost-vfio来理解vDPA的kernel实现流程。

vhost-vfio,从QEMU的观点来看,vhost-vfio就是一个新类型的QEMU网路后端用来支持virtio-net的设备。从kernel的观点来看,vhost-vfio就是vhost-mdev设备的用户态驱动。它的主要作用是:

  • 设置vhost-mdev设备:打开vhost-mdev的设备文件,用来传递vhost的命令到设备去,得到vhost-mdev设备的container,用来传递DMAsetup的命令到VFIO container。

  • 从virtio-net设备接收数据路径卸载的命令( set/get virtqueue 状态,set 脏页日志,功能协商等等),并把他们翻译vhost-mdev的ioctl。

  • 接受vIOMMU map和umap的命令并同VFIO DMA的ioctl执行。


    下面这个图在原文中是错误的,我基于自己的理解在使用最小的代价作做个修改。Redhat的blog比较坑爹,不能反馈,有认识的大侠可以去反馈一下。

这里有一个关键信息需要强调,对于vDPA的实现,我们这里使用的基于SRIOV的网卡VF,但是这里并没有强制要求SRIOV,网卡厂家可以使用其他的方式在一个物理网卡上运行多个vDPA的实例。在这里SRIOV的VF实现是基于Virtio的,只要提供基于标准的vritio layout,这里并不局限于设备的类型。比如,在Beta-Metal设计中,vDPA的设备可以是多个PF。


比如在Scalable IOV中,网卡并不是分解成VF,而是QP级别的粒度。

从下到上在回顾一下vDPA的框图:


  1.  在硬件层是vDPA设备,它可以使用私有的控制路径初始化virtqueue,在virtio Full hardware offloading时,这个设备是virtio-net 设备。

  2. virtio-mdev设备实现了vDPA设备的具体功能,就是我们如何卸载数据路径。virtio-mdev设备接受virtio-mdev基于API的传输命令,并完成mediated 设备的翻译,仿真或者中介的功能。

  3. virtio-mdev 传输API通过mdevbus提供了一个统一的API给用户态(qemu中)或者kernel的驱动。它本质上是一个driver的抽象设备。

  4. 对于host用户空间, vhost-mdev把自己注册成一个新的mdev设备,来bridge 用户空间的vhost驱动和virtio-mdev设备。它通过ioctl接受vhost-net兼容的命令,并把他们翻译成virtio-mdev的传输API。它同时属于VFIO group可以设置DMA。

  5. vhost-vfio是一个host 用户态的驱动,它和qemu中的virtio 设备一起对上面的VM提供一个虚拟化的virtio设备(例如virtio-pci). 从vIOMMU发出的DMA mapping 请求被转发到VFIO的contatier 句柄。而virtio设备的启动和配置都是通过vhost-mdev 来完成。

  6. 在Guest中,VFIO 会暴露设备和DMA API给用户态的驱动,这个例子是virtio-net的PMD。


vDPA DPDK 的实现


DPDK从18.05开始支持vDPA。它是基于vhost-user的协议提供了一个后端实现。DPDK的实现主要目的是实现一个可以DEMO的,为了最终实现一个更见标准的,在kernel里面的,基于mdev框架的实现。


这里有两个新的组件:

vDPA驱动,用户态驱动来控制vDPA设备硬件。

vDPA框架,提供vhost-user socket和vDPA驱动的连接。

DPDK vDPA框架提供一系列的设备回调函数,由网卡厂家实现,这些函数被vhost-user调用来创建数据路径。

在vDPA设备支持热迁移的脏页他tacking的场景下,它的diver可以也会实现migration_done这样的回调函数。否则,vDPA框架可以在热迁移的时候把路径切换到软件上来执行。


Combining vDPA and virtio full HW offloading

在之前讲Virtio全硬件卸载的场景,硬件设备实现了数据和控制路径,因此设备可以使用kernel的virtio-net驱动,或者DPDK的virtio PMD。


在一个场景里,全硬件卸载可以使用vDPA设备,数据路径还是全硬件卸载,而控制路径可以使用vDPA API。


相对于全卸载的virtio PMD模式,这样的好处是:


  1.  灵活: 它可以切换到其他的使用vDPA的硬件设备,或者回到全软件的路径。

  2. 热迁移:可以实现对于热迁移的支持,把virtio ring的处理切换到软件路径并利用qemu tracking 内存脏页。

  3. 标准化



这个POST主要讲了virtio 全硬件卸载和vDPA,这一节的确是最复杂的,包含了大量的用户态和核心态的实现。这个也说了,大家正在尝试使用vDPA的框架来替换掉现有的SRIOV的VM加速技术。在未来的Scale IOV中,vDPA也有足够的灵活性支持,不管是在VM还是在Container的情况下。


总之,在这个之后,在讲Container的网路加速之前,我们有必要搞一个SmartNIC 字典了。



[1]http://netoptimizer.blogspot.com/2014/05/the-calculations-10gbits-wirespeed.html

[2]https://www.prowesscorp.com/computer-latency-at-a-human-scale/

[3]https://people.netfilter.org/hawk/presentations/LCA2015/net_stack_challenges_100G_LCA2015.pdf

[4]https://www.dpdk.org/blog/2019/11/25/how-red-hat-is-using-dpdk/

[5]https://sdn.feisky.xyz/wang-luo-ji-chu/index-1/sr-iov

[6]https://lwn.net/Articles/783892/



高端微信群介绍

创业投资群


AI、IOT、芯片创始人、投资人、分析师、券商

闪存群


覆盖5000多位全球华人闪存、存储芯片精英

云计算群


全闪存、软件定义存储SDS、超融合等公有云和私有云讨论

AI芯片群


讨论AI芯片和GPU、FPGA、CPU异构计算

5G群


物联网、5G芯片讨论

第三代半导体群

氮化镓、碳化硅等化合物半导体讨论

储芯片群

DRAM、NAND、3D XPoint等各类存储介质和主控讨论

汽车电子群

MCU、电源、传感器等汽车电子讨论

光电器件群

光通信、激光器、ToF、AR、VCSEL等光电器件讨论

渠道群

存储和芯片产品报价、行情、渠道、供应链




< 长按识别二维码添加好友 >

加入上述群聊




长按并关注

带你走进万物存储、万物智能、

万物互联信息革命新时代

微信号:SSDFans
SSDFans AI+IOT+闪存,万物存储、万物智能、万物互联的闪存2.0时代即将到来,你,准备好了吗?
评论
热门推荐
相关推荐
我要评论
0
1
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦