网络IO的虚拟化模型小结
网络IO的虚拟化模型随着技术发展,出现了多种方式,例如emulation、para-virtualization、pass-through和SR-IOV等,本文试图对其做一个简单的总结。
- Emulation(仿真):
全虚拟化是最早出现的IO虚拟化方式,效率也最低。以接收网络报文为例,其处理步骤可以简单描述如下:
- 数据包到达主机物理网卡,向host CPU发出中断。QEMU创建的网桥(br0)它会分析报文目的地。如果目的地是host,调用host的中断处理函数;如果目的地是虚拟机的话将报文转发至TAP设备。之前初始化时qemu进程已经打开了TAP的字符设备。
- TAP设备由两部分组成,一侧是网络驱动,另一侧是字符设备驱动,前者负责接受来自物理网卡的数据报,后者则将报文转发至qemu进程。过程为:TAP 将字符设备的文件描述符置位,qemu进程通过select调用接收。
- qemu调用tap_send函数,将网络数据报通过e1000_receive函数写入网卡的缓存区,依次会调用pci_dma_write,最后是qemu_get_ram_ptr,做一次内存拷贝。在虚拟机中,网卡缓存可以通过DMA方式访问,但虚拟机的物理内存映射到qemu的虚拟内存区,因此虚拟机的OS读取的实际是qemu进程的缓存。最后调用set_ics向虚拟机注入中断。
- 虚拟机读取中断后引发VM-Exit,停止VM进程执行,进入root操作状态。KVM要根据KVM_EXIT_REASON判断原因。对于IO请求,其标志为KVM_EXIT_IO。因为kvm无法处理此操作,需要重新回到qemu的用户态,调用kvm_handle_io进行处理。
- Para-virtualization(半虚拟化)
可以认为是一种改进后的仿真模型,由各厂商提供虚拟网卡驱动,并加入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的使用:
- vhost在处理完请求(收到数据包),将buffer放到used ring上面之后,往call fd里面写入;
- 如果成功设置了irqfd,则kvm会直接中断guest。如果没有成功设置,则走以下的路径:
Qemu通过select调用监听到该事件(因为vhost的callfd就是qemu里面对应vq的guest_notifier,它已经被加入到selectablefd列表);
- 调用virtio_pci_guest_notifier_read通知guest;
- guest从used ring上获取相关的数据。
host_notifier的使用:
- Guest中的virtio设备将数据放入avail ring上面后,写发送命令至virtio pci配置空间;
- Qemu截获寄存器的访问,调用注册的kvm_memory_listener中的eventfd_add回调函数kvm_eventfd_add();
- 通过kvm_vm_ioctl(kvm_state, KVM_IOEVENTFD, &kick)进入kvm中;
- kvm唤醒挂载在ioeventfd上vhost worker thread;
- vhost worker thread从avail ring上获取相关数据。
- Pass-through
VMM直接将一个PCI设备分配给VM,通过iommu保证VM间内存访问不冲突。这种方式性能最快,但是一个设备只能给一个VM使用,灵活性差,而且不支持迁移。
- SR-IOV
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的支持。
网络IO的虚拟化模型小结的更多相关文章
- 四种主要网络IO虚拟化模型
本文主要为大家简要介绍VMware.Redhat.Citrix.Microsoft主要虚拟化厂商使用的4种主要的虚拟化IO模型 (emulation.para-virtualization.pass- ...
- [编织消息框架][网络IO模型]BIO
既然跟网络内容有关就不得不学习网络IO模型,时代在进步,技术也在进步,采取使用那种网络IO模型就已经确定应用程序规模 阻塞IO(blocking IO) 在linux中,默认情况下所有的socket都 ...
- [原] KVM 虚拟化原理探究(5)— 网络IO虚拟化
KVM 虚拟化原理探究(5)- 网络IO虚拟化 标签(空格分隔): KVM IO 虚拟化简介 前面的文章介绍了KVM的启动过程,CPU虚拟化,内存虚拟化原理.作为一个完整的风诺依曼计算机系统,必然有输 ...
- 5种网络IO模型
5种网络IO模型(有图,很清楚) 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到 ...
- 多路复用 阻塞/非阻塞IO模型 网络IO两个阶段
1.网络IO的两个阶段 waitdata copydata send 先经历:copydata阶段 recv 先经历:waitdata阶段 再经历 copydata阶段 2.阻塞的IO模型 之前写的都 ...
- Socket-IO 系列(一)Linux 网络 IO 模型
Socket-IO 系列(一)Linux 网络 IO 模型 一.基本概念 在正式开始讲 Linux IO 模型前,先介绍 5 个基本概念. 1.1 用户空间与内核空间 现在操作系统都是采用虚拟存储器, ...
- python网络编程——网络IO模型
1 网络IO模型介绍 服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种: (1)同步阻塞IO(Blocking IO):即传统的IO模型. (2)同步非阻塞IO(Non-bl ...
- 通过实例理解Java网络IO模型
网络IO模型及分类 网络IO模型是一个经常被提到的问题,不同的书或者博客说法可能都不一样,所以没必要死抠字眼,关键在于理解. Socket连接 不管是什么模型,所使用的socket连接都是一样的. 以 ...
- 【转】5种网络IO模型
5种网络IO模型(有图,很清楚) IO多路复用—由Redis的IO多路复用yinch Linux中对文件描述符的操作(FD_ZERO.FD_SET.FD_CLR.FD_ISSET
随机推荐
- 安卓APP开发简单实例 结对编程心得
开始说起搞APP开发,自己和小伙伴的编程水平真的很低,无从下手,只有在网上找点案列,学习着怎样开发,结对编程还是面临着许多问题的,大家的水平有所差异和编程风格不同,我们用eclipse做了一个仿微信登 ...
- Linux(Centos7)yum安装最新mysql
环境 CentOS 7.1 (64-bit system) MySQL 5.6.24 CentOS 安装 参考:http://www.waylau.com/centos-7-installation- ...
- linux虚拟化简介
为跨平台而生 在计算机发展的早期,各类计算平台.计算设备所提供的接口.调用方式纷繁复杂,没有像今天这样相对统一的标准.由于需要适配不同的平台,需要写很多繁琐的兼容代码,这无形中给开发者带来了很大的不便 ...
- JS思考遍历对象
var json={ “name”:”小明”, “age”:”10”, “sex”:”男” } for(var key in json); //key只是个变量名 console.log(key); ...
- MongoDB的基本操作(增删改查)
目录 概念整理 数据库:一个MongoDB中可以建立多个数据库. 集合:MongoDB的文档组. 文档:实际存放数据的地方. 常见的操作 数据库(新增,删除) 集合(新增,编辑,删除) 文档(增删 ...
- 离线服务器安装zabbix
因为机房内的服务器并不是所有都能上外网,所以利用zabbix官方源的安装方法就行不通了,又嫌弃编译安装麻烦,所以这里选择离线RPM包安装zabbix.(如需完整rpm包可以留言与我联系) 下载zabb ...
- python selenium模拟登陆qq空间
不多说.直接上代码 from selenium import webdriver driver = webdriver.Chrome() driver.get('http://qzone.qq.com ...
- JavaScript系列:函数式编程(开篇)
前言: 上一篇介绍了 函数回调,高阶函数以及函数柯里化等高级函数应用,同时,因为正在学习JavaScript·函数式编程,想整理一下函数式编程中,对于我们日常比较有用的部分. 为什么函数式编程很重要? ...
- Java 爬虫遇到需要登录的网站,该怎么办?
这是 Java 网络爬虫系列博文的第二篇,在上一篇 Java 网络爬虫,就是这么的简单 中,我们简单的学习了一下如何利用 Java 进行网络爬虫.在这一篇中我们将简单的聊一聊在网络爬虫时,遇到需要登录 ...
- Future类型的连锁的运用
Future类型的连锁的运用: 洗脸 刷牙 吃早饭 看电视 出门 串行: import scala.concurrent.{Await, Future} import scala.util.{Fail ...