网络IO的虚拟化模型随着技术发展,出现了多种方式,例如emulation、para-virtualization、pass-through和SR-IOV等,本文试图对其作一个简单的总结。 缓存
全虚拟化是最先出现的IO虚拟化方式,效率也最低。以接收网络报文为例,其处理步骤能够简单描述以下: 网络
能够认为是一种改进后的仿真模型,由各厂商提供虚拟网卡驱动,并加入Guest OS。vhost driver建立了一个字符设备 /dev/vhost-net,这个设备能够被用户空间打开,并能够被ioctl命令操做。当给一个Qemu进程传递了参数-netdev tap,vhost=on 的时候,QEMU会经过调用几个ioctl命令对这个文件描述符进行一些初始化的工做,而后进行特性的协商,从而宿主机跟客户机的vhost-net driver创建关系。与此同时,kernel中要建立一个kernel thread 用于处理I/O事件和设备的模拟。 kernel代码 drivers/vhost/vhost.c:在vhost_dev_set_owner中,调用了这个函数用于建立worker线程(线程名字为vhost-qemu+进程pid)。这个内核线程被称为"vhost worker thread",该worker thread的任务即为处理virtio的I/O事件。而在Guest中,会打开virtio设备,将virtio的vring映射到host kernel。vhost与kvm的事件通讯经过eventfd机制来实现,主要包括两个方向的event,一个是Guest到Vhost方向的kick event,经过ioeventfd承载;另外一个是Vhost到Guest方向的call event,经过irqfd承载。 函数
guest_notifier的使用: 性能
Qemu经过select调用监听到该事件(由于vhost的callfd就是qemu里面对应vq的guest_notifier,它已经被加入到selectablefd列表); spa
host_notifier的使用: 线程
VMM直接将一个PCI设备分配给VM,经过iommu保证VM间内存访问不冲突。这种方式性能最快,可是一个设备只能给一个VM使用,灵活性差,并且不支持迁移。 blog
SR-IOV主要用来解决pass-through只能被一台虚拟子机访问的问题。SR-IOV标准由PCI-SIG,这个标准实现须要CPU、芯片组和PCI设备(主要是网卡等I/O资源)协同在硬件层面实现。支持SR-IOV功能的网卡能够在Hypervior里面注册成多个网卡(每一个网卡都独立的中断ID、收发队列、QOS管理机制)。每一个设备能够经过pass-through方式分配给虚拟子机。Intel公司的82599 10G网卡以PF/VF的形式提供了对SR-IOV的支持。 队列