- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章浅谈Linux设备虚拟化技术的演进之路由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
设备虚拟化技术,一直是云计算领域最重要的基础技术之一。我们在虚拟机里面看到的形形色色的设备,比如:网卡,磁盘,键盘,鼠标等,都离不开这项技术的帮助。这篇文章,我们将从技术演进的角度来谈一谈 Linux 现有的以及即将到来的设备虚拟化技术.
在最早期阶段,设备虚拟化常常和机器模拟器技术,比如:QEMU,绑定在一起。我们可以通过 QEMU 模拟真实设备的所有寄存器布局和操作流程,当 QEMU 虚拟机里面设备驱动需要访问该虚拟设备的寄存器时,这条访问指令会被 trap 到 QEMU,由 QEMU 来进行处理。这样,虚拟机里面的设备驱动在操作该虚拟设备时就像在访问真实的硬件设备一样,设备驱动也不需要任何变更.
通过上述这种 trap-and-emulate 的方式来模拟设备,虽然不需要对真实设备驱动进行变更,但是设备访问过程中,频繁的陷入@amp;陷出带来了严重的性能问题,因此,virtio 这类半虚拟化技术应运而生,并于 2008 年合入 Linux 内核主线.
相较于 trap-and-emulate 这种方式,Virtio 不再拘泥于依赖已有的设备驱动,而是定义了一套全新的专用于虚拟设备的驱动框架。设备驱动清楚自己是在操作虚拟设备,因此,在真正的 I/O 路径上规避了大量可能导致陷入@amp;陷出的 mmio/pio 操作,从而提高了性能。虚机里面的 Virtio 驱动和 QEMU 模拟的 Virtio 设备的数据交互,本质上是一套基于共享内存 + 环形队列的通信机制。核心数据结构(split virtqueue)包括:两个 ringbuffer (avail ring, used ring) 和一个 descriptor table。工作机制类似 DMA,虚机内 virtio 驱动首先会将一个请求在内存中需要传输的散列 buffer 的地址、长度组成一个个描述符写入到 descriptor table 中,然后将这些描述符对应的 descriptor table 上的 index 写入到 avail ring 中,并通过 eventfd 机制通知到宿主机上的 virtio backend。由于这些 ringbuffer、descriptor table 以及散列 buffer 都在共享内存中(虚机本质上是一个用户态进程,因此虚机内存是由用户态申请和分配,并可以 share 给其他进程,如:SPDK,DPDK 等),因此,Virtio Backend 可以直接访问并获取到散列 buffer 的地址、长度,进而直接存取这些散列 buffer。当处理完请求之后,Virtio Backend 将数据填充到相应的 buffer,并将对应的 descriptor table index 写入 used ring 中,并通过 eventfd 机制注入中断通知虚机内 virtio 驱动.
Virtio 技术提出之后,Virtio 设备通常是在 QEMU 里面来进行模拟,数据收发都需要经过 QEMU,再到虚机内部。但逐渐地,开发者们发现,当模拟网卡时,在 QEMU 里面进行数据收发,最终都需要通过系统调用的方式,陷入内核来操作网卡硬件进行实际的数据收发。那么,QEMU 到内核的这次上下文切换以及带来的额外拷贝开销,有没有办法优化呢?
Linux 内核社区最终在 2010 年合入了 vhost 这个技术来进行优化,通过将 virtio 的数据面 offload 到一个内核线程来进行处理,这样 virtio 通信机制从原本的 QEMU 用户态 I/O 线程和虚机驱动(QEMU 用户态 vcpu 线程)通信变成了 vhost 内核 I/O 线程和虚机驱动(QEMU 用户态 vcpu 线程)通信。vhost 内核 I/O 线程拿到数据包之后,直接走内核协议栈和网卡驱动进行处理,从而优化掉了 QEMU 到内核态的额外开销.
随着云计算规模的不断扩大,用户一方面不再满足于 Virtio 这类半虚拟化设备带来的性能体验,另一方面 GPU 这类很难进行 virtio 化的设备应用场景与日俱增。在这种背景下,VFIO 这项技术被提出并在 2012 年合入 Linux 内核主线。VFIO 全称是 Virtual Function I/O,它实际是一个用户态设备驱动框架,相较于更早的 uio 这个用户态设备驱动框架,VFIO 能够有效利用硬件 IOMMU 机制进行安全隔离,从而能够广泛地应用在云计算这类有多租户需求的场景中.
如上图所示,通过 VFIO,QEMU 能够直接将自己虚拟出的一个 PCI 设备和一个物理 PCI 设备的数据链路直接打通,当虚拟机里面的设备驱动访问虚拟 PCI 设备的 bar 空间时,通过 EPT 机制,这次 mmio 访问会被重定向到真实物理设备相应的 bar 空间位置,而不再需要 trap 到 QEMU。这样,虚机驱动就相当于可以以接近零消耗的方式直接访问真实物理设备,性能可以达到最佳。同时,VFIO 驱动利用 IOMMU 实现了设备 DMA 和中断的重映射,一方面起到隔离作用,即某个虚机无法操作 VFIO 直通设备向同一宿主机上的其他虚机发起 DMA 和中断,一方面也保证了设备进行 DMA 时通过给定的虚机物理地址能够直接访问到正确的物理内存.
虽然,VFIO 能够给虚机带来接近物理机的 I/O 性能体验,但该技术仍存在一个缺陷,即不支持热迁移,带 VFIO 设备的虚机将没法像传统带 virtio 设备的虚机那样进行热迁移。这就使得开发者们,又开始探寻新的既能满足性能需求又具备运维灵活性的设备虚拟化技术。2014 年 QEMU 社区合入的 vhost-user 技术就是其中之一,由于 QEMU 和 vhost 的线程模型对 I/O 性能的优化并不友好,而且由每个虚机单独分出线程来处理 I/O 这种方式从系统全局角度来看可能也并不是最优的,因此,vhost-user 提出了一种新的方式,即将 virtio 设备的数据面 offload 到另一个专用进程来处理。这样,由于是专用进程,线程模型不再受传统 QEMU 和 vhost 线程模型制约,可以任意优化,同时,还可以以 1:M 的方式同时处理多个虚机的 I/O 请求,而且相较于 vhost 这种内核线程方式,用户进程在运维方面更加具备灵活性,vhost-user 框架在提出之初,就受到广泛关注,并引申出了 SPDK 和 OVS-DPDK 这类以 polling + 用户态驱动为核心的新的虚机 I/O 服务模型.
VFIO 技术在实际应用场景,除了之前提到的不支持热迁移的问题外,还有一个限制就是一个设备只能透传给一个虚机,无法做到资源共享。SR-IOV 技术从某种程度上能够解决这个问题,即将一个物理 PCI 设备从硬件层面进行资源划分,划分成多个 VF,透传给多个虚机进行使用,但是有很多设备可能并不具备 SR-IOV 能力,因此,Linux 内核社区在 2016 年合入了 VFIO-mdev 这个技术框架,希望提供一个标准的接口来帮助设备驱动实现软件层面的资源切分并能够利用 VFIO 技术透传给虚机.
该技术本质上是在内核实现了一个虚拟设备(Mediated device)总线驱动模型,并在 VFIO 内核框架上进行了扩展,增加了对 mdev 这类虚拟设备的支持(mdev bus driver),从原来只支持从标准的硬件 PCI 设备和硬件 platform 设备获取透传信息,比如:PCI bar 空间,变成了既支持直接从硬件设备获取又可以从 mdev 设备驱动定义的虚拟设备接口来获取。这样,比如,当需要将一个 PCI 设备的 bar 空间作为资源切分的话,通过实现合适的 mdev 设备驱动,就可以将 bar 空间以 4KB(页面大小)为粒度,分别透传给不同虚机使用.
VFIO 和 virtio 这两类技术一直是最主流的设备虚拟化技术。VFIO 能够直接将硬件资源透传给虚机使用,性能最佳,virtio 性能稍逊,但胜在更加灵活。那有没有可能将两者的优势结合起来呢?2020 年被合入 Linux 内核主线的 vDPA 技术框架,就是为了实现这一目标.
vDPA 的全称是 Virtio Data Path Acceleration,它表示一类设备:这类设备的数据面处理是严格遵循 Virtio 协议规范的,即驱动和设备会按照第三节提到的 Virtio 通信流程来进行通信,但控制路径,比如:通信流程里面提到的 ring buffer 和 descriptor table 的内存地址,驱动如何告知设备,设备支持的特性,驱动如何感知,这些都是厂商自定义的,不一定会遵循 Virtio 协议。这样做的好处是,可以降低厂商在实现这类设备时的复杂度.
Linux 内核为了将这类设备应用起来,就提出了 vDPA 这样一个技术框架。这个技术框架本质上和 VFIO-mdev 类似,也实现了一个虚拟设备(vDPA device)总线驱动模型,和 VFIO-mdev 不同的是,通过 vDPA 框架虚拟出来的设备,既可以给虚机使用,又可以直接从宿主机(比如:容器)进行访问。这一切都归功于,vDPA 设备的数据路径是遵循 Virtio 协议规范的,因此,可以直接被宿主机上的 virtio 驱动直接访问。同时,该技术框架对 vhost 内核子系统进行了扩展,赋予了类似 VFIO 技术框架的功能,允许将 vDPA 设备用来进行数据通信的硬件资源(ring buffer, descriptor table,doorbell 寄存器等)透传给虚机使用,这样,虚拟机的 virtio 驱动进行数据通信时,也是直接访问硬件资源,而不再需要通过 vhost、vhost-user 等方式进行处理了。更重要的一点是,由于虚机驱动是原本的 virtio 驱动,因此,当需要支持热迁移时,QEMU 可以灵活切换会软件模拟的方式,来保证热迁移的顺利进行。这样,vDPA 这个设备虚拟化技术框架既保证了最佳性能又保留了 virtio 设备的灵活性,而且还统一了虚机和容器的 I/O 技术栈.
通过上述 vDPA 技术框架,我们基本解决了长期以来设备虚拟化技术在虚机场景下暴露的一些问题,而更重要的是,它将 virtio 技术也带到了容器领域。但这个技术框架还存在一个问题,就是需要硬件设备的支持。回想之前提到的 virtio、vhost、vhost-user,本质上都是软件定义的虚拟设备。那 vDPA 这个技术框架有没有可能也能够使用软件定义的设备呢?VDUSE 这项技术就是用来实现这个目标的,通过 VDUSE,我们可以在一个用户进程实现一个软件定义的 vDPA 设备,并可以通过上述 vDPA 框架接入 virtio 或者 vhost 子系统,供容器或者虚机使用.
该项技术是由我们自主研发并在去年 10 月向 Linux 内核社区正式开源的。现阶段我们的方案已经被合入 Linux 内核主线,将在 Linux 5.15 版本与大家见面。同时,我们也会在 9 月 15 日举办的 KVM Forum 这个虚拟化领域的高端技术论坛会议上进行线上分享.
从服务虚拟机到支持容器,从纯软件模拟到硬件直通再到软硬件结合,Linux 设备虚拟化技术这几十年里一直在朝着极致性能、应用灵活等方向不断演进。随着云原生的浪潮,各大硬件厂商的入局,全新的软硬件结合方式不断涌现,我们相信后续也会有更多精彩技术在等待着我们.
原文地址.:https://mp.weixin.qq.com/s/g1kt0DDJwDk2Lg56R5suKw 。
最后此篇关于浅谈Linux设备虚拟化技术的演进之路的文章就讲到这里了,如果你想了解更多关于浅谈Linux设备虚拟化技术的演进之路的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
iphone设备UDID、iphone设备ID和iphone设备Token之间有什么区别? 通常,当我们使用苹果推送通知服务时,会使用 iPhone 设备 token 。 但我的目标只是识别唯一的 i
我们使用 firebase 从服务器向 Android 和 IOS 设备发送通知,并且我们使用旧版 FCM 发送通知。但是当我们的应用程序在后台时,通知由系统本身处理,因此我们无法通过应用程序处理它。
在 Google 上搜索后,我发现人们说只能通过“MFi 程序”将 iOS 设备与非 iOS 设备连接起来。这是真的吗? 我的项目主要集中于直接通过蓝牙与Arduino设备发送和接收信息。 iOS和非
所以我有一个通用应用程序,我正在设置 UIScrollView 的内容大小。显然,iPhone 和 iPad 上的内容大小会有所不同。如何为 iPad 设置某种尺寸,为 iPhone 和 iPod t
问题:如何在 pod 中使用连接到主机的原始设备作为 block 设备。 我尝试使用类型为“BlockDevice”的“hostPath” volumes: - my-data: hostPath
Implemented GCKDeviceScannerListener Singleton Class on ViewController, however its delegate methods
我有一个 (PhoneGap) 应用程序,它将成功获得 Passbook 通行证,并且还将成功接收与 Passbook 分开的推送通知(当伪造设备 ID 时)。 我遇到的问题是发送给注册设备的设备 I
我正在尝试找到一种方法,通过我目前正在使用的 iOS 应用程序访问我的信标的电池电量。我正在使用 Kontakt 的 iBeacon 设备。我浏览了 Estimote iOS SDK,他们提供了一种实
我正在努力让 CUDA 应用程序也能监控 GPU 的核心温度。可通过 NVAPI 访问该信息。 问题是我想确保在运行代码时监控的是同一个 GPU。 但是,似乎有信息表明我从 NvAPI_EnumPhy
从沙箱模式到生产模式,设备 token 有何不同? 我认为我已将一些设备 token 锁定为生产模式,并且无法将它们从开发中插入。 关于如何检查有什么想法吗? 最佳答案 当您使用开发证书构建应用程序时
目录 /run/user/1000/gvfs 和 ~/.gvfs 分别是空的和不存在的。我的图形文件管理器 (Thunar) 能够检测和访问设备的内部和外部存储器。 命令 gvfs-mount -l
我有一个 Android 平板电脑,它有一个迷你 USB 端口和一个 USB 端口,我想编写一个与 USB key 通信的应用程序。我写了一个demo来找出U盘,但是没有任何反应。 令我不安的是,如果
我们将 PHP 版本从 5.4.25 更改为 5.4.45,并在服务器上安装了 MS SQL 驱动程序。在更改服务器之前,一切正常,但在更改服务器之后,我遇到了 Web 服务问题。我们的身份验证 So
我想知道是否有人使用此 API 在 Android 设备上同时从 2 个后置摄像头捕获图像或视频:https://source.android.com/docs/core/camera/concurr
我正在为客户构建一个物联网解决方案,网络管理员坚持要求设备仅通过访客网络进行连接,该网络有一个强制门户,其中的服务条款必须通过按下 UI 按钮来接受,然后才能获得外部互联网访问。到目前为止,我见过的大
我无法弄清楚这里的格式规则..在我的示例中,代码行太多,无法为每行添加 4 个空格,因此这里是我需要帮助的代码的链接 http://nitemsg.blogspot.com/2011/01/heres
如果我在我的设备上接受推送通知,并且不保存设备 token ,那么我如何在自定义 View 中查看设备 token 或恢复警报 View ? 我删除了应用程序并重新安装,但看不到设备 token 警报
我试图找出在尝试并行比较和复制设备 block 与 pthreads 时我做错了什么。看起来我正在脱离同步并且比较阶段无法正常工作。任何帮助将不胜感激 #ifndef __dbg_h__ #defin
我刚刚写完所有这些内容,但这个红色的小栏告诉我我不能发布图片或两个以上的链接。因此,如果您可以引用 this Imgur album , 那简直太好了。谢谢。 我在这里相对较新,甚至对 android
我需要启用 mysql 常规日志并将其通过 nsf 移动到我系统中的另一个驱动器/设备! 所以,我在 my.cnf 中启用了它: general_log = 1 general_log_fi
我是一名优秀的程序员,十分优秀!