DPDK virtio-user介绍及使用 笔记

KVM中Virtio网络的演化之路_virtio kvm-CSDN博客 

1.virtio-net驱动与设备最原始的virtio网络

 

2.vhost-net处于内核态的后端

 

3.vhost-user使用DPDK加速的后端

 

4.vDPA使用硬件加速数据面

Virtio作为一种半虚拟化的解决方案,其性能一直不如设备的pass-through,即将物理设备(通常是网卡的VF)直接分配给虚拟机,其优点在于数据平面是在虚拟机与硬件之间直通的,几乎不需要主机的干预。而virtio的发展,虽然带来了性能的提升,可终究无法达到pass-through的I/O性能,始终需要主机(主要是软件交换机)的干预。

vDPA(vhost Data Path Acceleration)即是让virtio数据平面不需主机干预的解决方案

 

 

 

DPDK virtio-user介绍及使用 —lvyilong316

DPDK和容器直接的对接方案,我们知道容器(如Docker)网络一般都采用tap+bridge方案,也就是基于内核的网络通信,即使使用ovs一般也是kernel ovs,而不是dpdk-ovs。那么当我们使用的vswitch是基于DPDK时如何和容器对接呢

OVS - 简介 - 知乎 (zhihu.com)

OVS是一个高质量的,多层虚拟交换机(网络分层的层),其目的是让大规模网络自动化可以通过编程扩展,同时仍然支持标准的管理接口和协议:NetFlow. SFlow ... 等,并且它还支持多个物理机的分布式环境。详情请见http://openvswitch.org / http://lamoop.com/post/2013-11

ovs组成:

1. ovsdb-sever: OVS的数据库服务器,用来存储虚拟交换机的配置信息。它于manager和ovs-vswitchd交换信息使用了OVSDB(JSON-RPC)的方式。

2. ovs-vswitchd: OVS的核心部件,它和上层controller通信遵从OPENFLOW协议,它与ovsdb-server通信使用OVSDB协议,它和内核模块通过netlink通信,它支持多个独立的datapath(网桥),它通过更改flow table实现了绑定,和VLAN等功能。

3. ovs kernel module: OVS的内核模块,处理包交换和隧道,缓存flow,如果在内核的缓存中找到转发规则则转发,否则发向用户空间去处理。

ovs原理-内核流表-01 - 知乎 (zhihu.com)

OVS 和 OVS-DPDK 对比

DPDK和kernel通信的常用方式

DPDK和kernel直接的通信路径也叫做exception path,DPDK支持几种方式让用户空间的报文重新进入内核协议栈。

TAP/TUN设备

Kernel NIC Interface(KNI)

virtio-user+vhost-net

网络虚拟化——virtio

原文链接:https://blog.csdn.net/dillanzhou/article/details/120339795
virtio作为一种通用的虚拟IO设备驱动模型,主要定义了两方面的标准模型和接口:控制面的设备配置和初始化,以及数据面的数据传输。

上图是在qemu/kvm虚拟机中实现virtio的架构。可见基本逻辑和其他虚拟网卡是相同的,只是交互方式通过vring队列实现

virtqueue:数据传输模型

virtio中定义了virtqueue作为guest驱动和host后端间的数据传输结构。块设备只需要一个virtqueue用于数据读写,而网络设备则需要两个virtqueue分别用于网络报文的收和发。

1. virtio作为通用的IO虚拟化模型,是如何定义通用的IO控制面和数据面接口的?或者说,基于virtio的网络设备virtio-net和块存储设备virtio-blk,有哪些共通点?

对于控制面,virtio为每个设备封装了virtio_config_ops接口,用于配置和启动设备。

对于数据面,virtio定义了virtqueue抽象传输模型,virtqueue提供了一系列操作接口来完成数据收发和事件通知。virtio_config_ops中的find_vqs接口提供了virtqueue的创建和获取能力。virtqueue具体通过virtio-ring实现,driver向available ring中输入请求,host backend处理请求后向used ring中输入回应。

上述模型和实现是virtio设备通用的,virtio-net和virtio-blk都基于这套模型和接口实现。不同之处只在于使用的virtqueue数量,以及virtqueue/vring中的请求/回应的结构与内容不同,这些都和设备的具体功能和行为密切相关。

2. 在linux内核下,有virtio、virtio-pci、virtio-net、virtio-blk等virtio相关驱动。这些驱动是如何组织的,多个驱动间是什么关系?

linux内核中和virtio相关的驱动主要有:virtio、virtio_ring、virtio_pci、virtio_net、virtio_blk等。其中:

virtio提供了virtio总线和设备控制面的接口。

virtio_ring提供了数据面,也就是virtqueue接口和对应的vring实现。

virtio_pci提供了virtio设备作为PCI设备加载时的通用驱动入口,它依赖virtio和virtio_ring提供的接口。

virtio_net提供了virtio网络设备的标准驱动,它依赖virtio和virtio_ring提供的接口。virtio_net将自己注册为virtio总线的一种设备驱动。

virtio_blk提供了virtio块存储设备的标准驱动,它依赖virtio和virtio_ring提供的接口。virtio_blk将自己注册为virtio总线的一种设备驱动。

3. 一个virtio设备,是如何加入到虚拟机设备模型中,被内核发现和驱动的?

一个virtio PCI设备加载时,内核会尝试所有注册的PCI设备驱动,最后发现可以被virtio_pci驱动。virtio_pci再调用注册到virtio总线上的设备驱动,最后发现可以被virtio_net驱动。virtio_net通过virtio_pci的标准配置接口和host协商设备特性和初始化设备,之后通过virtio_ring提供的接口收发网络数据。

4. virtio-net具体又提供了哪些标准接口?控制面和数据面接口是如何定义的?

virtio设备的控制面和数据面接口都是标准的,只是具体数据格式和含义有区别。virtio-net有自己的feature bit集合,每个virtio-net设备至少使用两个virtqueue用于报文的收和发。virtio-net收发的数据buffer都包括virtio_net_hdr作为头部,用于表示driver和host设置的offload参数。

5. virtio技术为虚拟化而产生,但它能否脱离虚拟化环境使用?例如在普通的容器环境或者物理机环境?

理论上说,virtio设备需要driver和host后端两部分协同完成。在非虚拟化环境下,这个后端可以是内核的vhost模块。vhost模块是在内核中实现的virtio后端功能,是为了进一步提升virtio设备的效率而产生的:

virtio为虚拟IO设备提供了一套标准的接口和实现。同时由于其半虚拟化的特质,virtio驱动在设计和实现时尽可能减少了主要操作路径上会触发host后端操作(vmexit)的指令以提升IO效率。但在执行IO操作时,仍会不可避免的需要触发后端操作。例如virtio-net驱动发包时,在向tx virtqueue写入buffer后必然要kick后端来处理buffer,这个kick就是一个IO写操作。当后端在用户态qemu进程中实现时,这就需要经过guest driver->kvm->qemu->kvm->guest的过程,和普通的虚拟设备驱动是没有区别的,效率仍然低下。为了缩短这个过程,后端实现被放入了内核态,作为一个内核模型/内核线程运行,也就是vhost。有了vhost后,后端操作的流程就变成了guest driver->kvm->vhost->kvm->guest。看似和之前差不多,但是kvm和vhost之间的交互只是一个内核函数调用,性能比之前的kvm和qemu间的用户/内核切换要好的多。同时,使用vhost也提升了后端完成实际IO操作的性能。大部分情况下,后端完成IO操作(例如块设备读写或网络收发)仍然要通过内核接口,例如qemu仍然需要使用文件或socket接口实现,这又需要引入系统调用和状态切换。而使用vhost之后,这些内核能力可以由vhost模块直接调用,又一次减少了状态切换开销。

基于vhost,virtio设备其实不一定需要在虚拟化环境下使用,可以在用户态实现virtio驱动,在初始化时直接与vhost交互完成配置,这样就可以在非虚拟化环境下实现一个用户态的纯虚拟virtio设备。

网络虚拟化——vhost

virtio为虚拟IO设备提供了一套标准的接口和实现。同时由于其半虚拟化的特质,virtio驱动在设计和实现时尽可能减少了主要操作路径上会触发host后端操作(vmexit)的指令以提升IO效率。

但在执行IO操作时,仍会不可避免的需要触发后端操作。例如virtio-net驱动发包时,在向tx virtqueue写入buffer后必然要kick后端来处理buffer,这个kick就是一个IO写操作。当后端在用户态qemu进程中实现时,这就需要经过guest driver->kvm->qemu->kvm->guest的过程,和普通的虚拟设备驱动是没有区别的,效率仍然低下。此外,qemu在向外转发报文时,仍然需要通过系统调用将报文交给内核发送,这又是一次用户态和内核态的切换。

为了缩短这个过程,一种直接的思路就是将virtio后端的实现也放入内核态,作为一个内核模块/内核线程运行。这个思路和KVM类似,将qemu原本在用户态完成的模拟能力转移到内核模块中实现,只是这里要转移的是qemu的设备模拟功能。这项技术称作vhost。

有了vhost后,后端操作的流程就变成了guest driver->kvm->vhost->kvm->guest。看似和之前差不多,但是kvm和vhost之间的交互只是一个内核函数调用,性能比之前的kvm和qemu间的用户/内核切换要好的多。同时,使用vhost也提升了后端完成实际IO操作的性能。大部分情况下,后端完成IO操作(例如块设备读写或网络收发)仍然要通过内核接口,例如qemu仍然需要使用文件或socket接口实现,这又需要引入系统调用和状态切换。而使用vhost之后,这些内核能力可以由vhost模块直接调用,又一次减少了状态切换开销。

redhat的两篇介绍virtio/vhost的文章

Introduction to virtio-networking and vhost-net

Deep dive into Virtio-networking and vhost-net

vhost是一种在内核中提供virtio设备后端功能的技术,其出发点是用于改善虚拟环境下virtio设备的IO性能,避免qemu在用户态实现后端功能所需的大量状态切换和系统调用。

vhost定义了一种基于消息的协议,通过这个协议,virtio后端可以将virtio设备的数据面配置信息转发给另一个组件,从而让这个组件去完成数据面的功能。也就是说,采用vhost技术后,virtio后端的控制面和数据面可以分离成两个组件,控制面组件在完成基本配置后使用vhost协议将数据面配置下发给数据面组件,后续的数据交互由数据面组件实现。

vhost协议只定义了数据面配置的下发规范,数据面能力的具体实现方式由接收vhost消息的组件自己决定。

通过vhost协议,控制面组件主要下发两类数据面配置信息:

virtio后端的内存布局信息,通过这些信息,vhost组件才能够访问virtqueue和virtio driver提供的buffer内存地址一对文件描述符(fd),用于vhost组件与virtio driver间收发通知事件。在kvm场景下这两个fd在vhost和kvm间共享,双方通过这两个fd来互相通知事件,而不需要qemu的参与。

1. vhost支持的是控制面还是数据面的能力?

vhost协议只定义了数据面配置的下发接口,不涉及控制面的能力。vhost-net的实际实现中也是根据接口下发的数据面配置进行数据面交互,不包括控制面的协商和初始化。

2. vhost如何与virtio驱动交互获取控制面信息或数据面数据?

vhost协议并没有规定vhost如何获取配置信息。内核实现的vhost-net是通过对/dev/vhost-net执行ioctl来完成配置的。

3. vhost在获取了virtio设备的操作请求后如何实现后端功能?

vhost根据配置信息获得virtqueue/vring的内存地址,之后就可以通过vring收发数据,vhost-net通过一个tap设备在vring和host间转发报文。vhost配置时还会获得两个fd,用于接收和发送事件通知。

4. 采用vhost后,virtio设备实现是否还依赖于qemu的功能?可否在没有qemu,甚至非虚拟化场景下使用virtio/vhost架构?

在虚拟化场景下,目前的virtio设备仍然依赖qemu实现控制面的协商和vhost-net的配置。但从理论上说qemu并不是必须的,在非虚拟化场景下可以由其他组件来完成virtio虚拟设备的配置。例如DPDK中就支持了virtio-user模式,可以在host用户态进程中直接完成virtio设备配置,并与vhost-net或vhost-user交互,并不需要qemu和kvm来虚拟出一个virtio pci设备。这个模式主要用于在容器网络中使用DPDK,以及让DPDK与内核通信的场景。

5. vhost是否和virtio一样是通用架构,使用vhost支持virtio-net、virtio-blk的后端功能是如何实现的?

vhost协议和具体设备类型无关,linux内核中有vhost模块实现vhost的通用标准接口。除了常用的vhost-net外,也有vhost-blk、vhost-scsi等磁盘块设备的vhost实现。但这些实现并没能进入内核。vhost-blk至少有3次被不同作者提交到内核社区,都没能被合入,主要原因是和qemu中的后端相比性能优势不大,因此没有明显的合入价值。

6. vhost-net是如何实现的,使用vhost-net后virtio-net设备的网络数据收发路径是怎样的?

使用vhost的数据路径大致是virtio-net<-->vhost-net<-->tap<-->kernel stack<-->nic。                       
原文链接:https://blog.csdn.net/dillanzhou/article/details/120558672

网络虚拟化——vhost-user

网络虚拟化——vhost-user-CSDN博客

在DPDK应用中实现vhost能力,从而在用户态也能达到跳过qemu,让guest virtio driver与外部网络栈高效通讯的效果。DPDK中已经提供了对这个方案的实现支持,称作vhost-user

1. vhost-user如何初始化数据面信息?

vhost-user通过unix socket与qemu进程通信,获取virtqueue的配置信息和内存布局,然后通过mmap实现和qemu/guest的共享内存通信。

2. vhost-user如何和virtio驱动实现共享内存?

如上,vhost-user获取virtqueue内存布局后,通过mmap实现共享内存。

3. vhost-user如何与virtio驱动间实现kick/notify事件通知?

在虚拟机模式下,vhost-user还是和KVM间通过eventfd互相通知事件。KVM再把virtio驱动的kick翻译成ioeventfd写,将vhost-user的irqfd写翻译成guest的irq中断。

4. vhost-user与在qemu中实现的virtio后端有什么区别?

理论上说差别不大,qemu也可以内置vhost-user的实现。只是如果在qemu中实现vhost-user,那么qemu还需要通过另一个队列和DPDK网络应用通信来收发网络数据,因此不如直接将vhost-user集成到DPDK网络应用中效率更高。

5. 除vhost外,virtio驱动能否也运行在用户态?

当然可以,DPDK提供的virtio的用户态驱动virtio-pmd。

6. virtio与vhost如何在非虚拟化场景,没有qemu/kvm介入的情况下运行?

在virtio-pmd的基础上,DPDK提供了virtio-user这个纯用户态的虚拟virtio设备实现。virtio-user可以和vhost-user/vhost-net在非虚拟化环境下交互。在这种模式下,已经不需要qemu/kvm提供virtio-pci设备模拟。virtio-user明确知道自己驱动的是一个纯软件模拟的virtio设备,仍然通过ioctl/unix socket方式将virtqueue配置和内存布局、以及eventfd发送给vhost-net/vhost-user。只是virtio-user现在也直接操作eventfd来实现kick/notify,因为没有了KVM/qemu的模拟实现。

                        
原文链接:https://blog.csdn.net/dillanzhou/article/details/120877753

virtio-pmd
virtio-pmd是DPDK中实现的virtio设备的PMD(poll mode driver)。virtio-pmd通过VFIO接口实现对虚拟/物理virtio网卡的用户态配置和数据处理。与其他网卡设备的PMD相比,virtio-pmd没有什么明显的特别之处。

virtio-user
virtio-user是在virtio-pmd的基础上,完全在用户态实现的virtio虚拟设备。virtio-user与传统的虚拟化技术完全无关,不再需要qemu/kvm等hypervisor介入。virtio-user相当于在用户态进程内同时实现了virtio-pmd和qemu的virtio后端控制面配置能力。

在virtio-user模式下,virtio设备挂载在DPDK内部虚拟的vdev总线上。virtio-user直接与vhost-net/vhost-user交互配置和初始化,通过ioctl/unix socket方式将virtqueue配置和内存布局、以及eventfd发送给vhost-net/vhost-user。之后,virtio-pmd会直接通过操作eventfd的方式来实现和vhost端的事件通知。

原文链接:https://blog.csdn.net/dillanzhou/article/details/120942808

用户态驱动技术有两种:UIO和VFIO。早期版本的DPDK只支持UIO框架,从DPDK1.7开始也支持VFIO。目前VFIO已经是DPDK的主要用户态驱动框架,从DPDK20.02版本开始基于UIO框架的igb_uio模块不再默认编译,文档也不建议再使用UIO。

UIO
UIO是“Userspace I/O”的缩写,是一种相对简单的用户态驱动框架。linux内核中包含了uio.ko内核模块,提供了框架功能。UIO的原理是为每个注册使用UIO的设备生成一个/dev/uioX的字符设备,通过这个字符设备,用户态程序可以实现设备内存空间映射(mmap)、设备中断开关(write)、设备中断获取(read)等操作。

VFIO
VFIO是“Virtual Function I/O”的缩写,但事实上VFIO并不专用于Virtual Function。DPDK的物理网卡pmd也都使用VFIO支持。因此内核VFIO模块的maintainer Alex Williamson建议将其称作“Versatile Framework for userspace I/O”——全能用户态IO框架。从这个解释就能看出,VFIO是对UIO的增强,特别是在前面提到的UIO的几个局限性上,VFIO给出了更完善的解决方案。

原文链接:https://blog.csdn.net/dillanzhou/article/details/120942808

                        

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值