Linux 操作系统原理网络 I/O 虚拟化

网友投稿 1396 2022-05-29

目录

文章目录

目录

IOMMU — CPU 硬件支撑的 I/O 虚拟化方案

需求背景

DMA Remapping Feature

IOMMU 硬件单元

PCI Passthrough

开启 IOMMU

UIO Framework — 用户态网络协议栈方案

VFIO — VNF/CNF 的用户态网络协议栈方案

IOMMU Group

IOMMU — CPU 硬件支撑的 I/O 虚拟化方案

需求背景

多个虚拟机共享服务器中的物理网卡,该场景中需要一种机制既能保证 I/O 的效率,又要保证多个虚拟机对用物理网卡共享使用。I/O 虚拟化的出现就是为了解决这类问题。

DMA Remapping Feature

从 CPU 的角度看,为了解决虚拟机访问物理网卡等 I/O 设备的性能问题,就是要避免 VMM 对 CPU 指令的捕获/翻译、上下文切换、内存拷贝等损耗,于是提出了 DMA Remapping Feature(DMA(直接存储器存取)的重映射功能),即:虚拟机可以通过 DMA Remapping Feature 直接访问到宿主机的物理网卡设备的内存空间,且进行安全访问,故称这段地址空间为:虚拟机对网卡访问的 DMA 保护域。

Linux 操作系统原理 — 网络 I/O 虚拟化

DMA Remapping Feature 主要解决了两个问题:

一方面为每个虚拟机创建了一个 DMA 保护域并实现了安全的隔离。

另一方面提供一种机制是将虚拟机的 Guest Physical Address 翻译为物理机的 Host Physical Address。从而虚拟机访问自己的地址就是直接访问宿主机分配给网卡的地址。

IOMMU 硬件单元

DMA Remapping Feature 的工作是通过 CPU 硬件平台的 IOMMU(I/O MMU,Input/Output Memory Management Unit,I/O 内存管理硬件单元)来完成的。IOMMU 的出现,实现了地址空间上的隔离,使设备只能访问规定的内存区域。

Intel VT-d 和 AMD-Vi 都是 IOMMU 的一种硬件实现:

Intel VT-d(Intel Virtualization Technology for Directed I/O,Intel 的直接 I/O 虚拟化):用于提高虚拟化的安全性、可靠性和 I/O 性能。

AMD-Vi(AMD’s I/O Virtualization Technology,AMD 的 I/O 虚拟化技术):作用同上。

PCI Passthrough

传统的虚拟化方案是虚拟机通过 Hypervisor 来共享的访问一个物理网卡,当 Hypervisor 需要处理多台虚拟机对同一个设备的并发访问和隔离时,Hypervisor 就成为了一个性能瓶颈。

那么,既然虚拟机可以通过 IOMMU 来访问网卡的 DMA,那么更彻底的做法就是把整块网卡 Passthrough(直通)给虚拟机使用,即:虚拟机绕过 Hypervisor 直接操作物理网卡。这种做法称作 PCI Passthrough。VMware,Xen 和 KVM 都支持这种技术。

主流的网卡设备商随即推出 SR-IOV(Single Root IO Virtualization)和 MR-IOV(Multi-Root IO Virtualization)技术,将一个 PF 硬件虚拟化为 VF,继而一张网卡可以化作多个 PCI/PCIe 设备,并 Passthrough 使用。

值得注意的是,在一些场景中,多个 PCI 设备之间是存在协作关系的,它们互相协作组成一个功能的实体,彼此之间也需要相互访问。而 IOMMU 对该场景中的这些设备是不适用的。

开启 IOMMU

Kernel 开启 IOMMU 之后就可以使用 Intel VT-d / AMD-Vi,以及 PCI Passthrough 功能了,同时还作用于应对故障及恶意行为的内存保护。

启用 IOMMU:

确保 CPU 支持 Intel VT-d / AMD-Vi,并且已经在 BIOS 中打开。

设置内核参数:

# Intel VT-d intel_iommu=on # AMD-Vi amd_iommu=on # Both,防止 Kernel 试图 Touching 无法 Passthrough 的设备。 iommu=pt

1

2

3

4

5

6

7

8

检查 dmesg 以确认 IOMMU 已经被正确启用:

$ dmesg | grep -e DMAR -e IOMMU [ 0.000000] DMAR: IOMMU enabled

1

2

UIO Framework — 用户态网络协议栈方案

UIO Framework Kernel Module(User Space I/O,用户态 I/O 框架内核模块),是 Kernel 提供的用户态 I/O 驱动程序框架。基于 UIO Framework 可以编写出让数据报文绕过 Kernel Network Stack,直接进入 User Space 进行处理的内核模块(e.g. DPDK IGB_UIO)。

但是,UIO 也有着不足之处,例如:不支持 DMA(不受 IOMMU 的保护)、中断支持有限、需要 Root 权限运行等,所以通过 DMA 传输大流量数据的 I/O 设备,如:被 Passthrougth 的网卡、显卡等设备,是无法使用 UIO Framework 的。

UIO 的实现机制是:对用户态暴露一个文件接口,当注册一个 UIO 设备时,就会出现一个系统文件 /dev/uioX,对该文件的读写就是对网卡设备的内存的读写。除此之外,对网卡设备的控制还可以通过 /sys/class/uio 下的各个文件的读写来完成。

如下图:

mmap() 接口:用于映射设备的寄存器空间。

read() 接口:用于等待一个设备中断。

write() 接口:用于控制中断关闭/打开。

VFIO — VNF/CNF 的用户态网络协议栈方案

上述:

UIO 的作用是支持用户态网络协议栈,问题是不支持 DMA。

IOMMU 的作用是支持 DMA Remapping 功能,问题是无法让多个 PCI 设备互相访问。

VFIO(Virtual Function I/O)就是 UIO 和 IOMMU 的升级版,兼顾两者的优点,实现了:

在 User Space 配置 IOMMU interface,继而可以将 DMA 地址空间映射限制在用户态进程的虚拟空间中。从而解决了 UIO 不支持 DMA 的问题。

Passthrough 的最小单元不再是某个单独的 PCI 设备,而是分布在同一个 IOMMU Group 的所有 PCI 设备;

可见,VFIO 最大的用途就是支撑 VNF 或 CNF 场景中 Passthrough 设备的用户态 I/O 实现。使用 VFIO 可以开发出安全的、非特权的、高性能的用户态的网卡驱动程序。

所以,VFIO 的本质与 UIO 一样,是一个用户态驱动框架。

一个 VFIO 设备表现为:

用户态呈现:一个 /dev/vfio 设备文件。

内核态呈现:一个 container 对象,一个 container 中可以包含多个 IOMMU Group。

它提供两种基本服务:

向用户态提供访问硬件设备的接口。

向用户态提供配置 IOMMU 的接口。

IOMMU Group

VFIO 是如何解决让多个 PCI 设备即 Passthrough 有可以互相访问的呢?换句话说:VFIO 如何让多个 PCI 设备一起 Passthrough?

为此 VFIO 引入了 IOMMU Group 的概念:

让若干个 VF(虚拟功能设备)同处于一个 IOMMU Group。

同时,把 IOMMU Group 作为 IOMMU 操作的最小单元。

即:一个 IOMMU Group 是将若干个 VFs 直通(Passthrough)给虚拟机的最小单位。

linux 网络 虚拟化

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:快速入门网络爬虫系列 Chapter16 | 爬虫性能提升
下一篇:“互联网+”大赛之智慧校园赛题攻略:你的智慧校园,WeLink帮你来建
相关文章