《深入浅出DPDK》读书笔记(十一):DPDK虚拟化技术篇(I/O虚拟化、CPU虚拟化、内存虚拟化、VT-d、I/O透传)

Table of Contents

DPDK虚拟化技术篇

X86平台上的I/O虚拟化

120.X86平台上的I/O虚拟化

121.X86平台虚拟化概述

122.CPU虚拟化

123.内存虚拟化

124.I/O虚拟化

1. I/O全虚拟化

2. I/O半虚拟化

3. I/O透传

125.I/O透传虚拟化

126.Intel®VT-d简介

127.PCIe SR-IOV概述

128.PCIe网卡透传下的收发包流程

129.I/O透传虚拟化配置的常见问题

130.小结

系列文章

相关阅读


 

DPDK虚拟化技术篇


成功,通常指在某一适当的时候在某一适当的地方做了一件适当的事情。——戈登·摩尔,英特尔公司创始人之一

随着虚拟化技术的兴起,越来越多业务和工作被迁移到虚拟机上执行。性能作为虚拟化技术商用的重要前提条件受到很多的关注。

为此,英特尔也特别推出Intel VT技术帮助硬件满足各种应用对性能的要求。而DPDK凭借着高效的工作模式,在I/O虚拟化的性能优化方面发挥着关键作用。

本篇将使用3章详细介绍如何利用X86平台上的虚拟化技术提高网络报文处理效率,以及在半虚拟化模式下DPDK如何加速报文处理的优化思路和实现。

第10章主要介绍Intel X86平台虚拟化技术,着重介绍I/O透传虚拟化技术,VT-d和SR-IOV,最后分析网卡的收发包流程在I/O透传和宿主机的不同点。

第11章简单介绍半虚拟化virtio的典型使用场景,详细讨论virtio技术,介绍virtio网络设备的两种不同的前端驱动设计,包括Linux内核和DPDK用户空间驱动。

第12章承接前一章的内容,介绍后端vhost的发展和技术架构,重点讲解DPDK在用户态vhost的设计思路以及优化点,并给出简要示例介绍如何使用DPDK进行vhost编程。


X86平台上的I/O虚拟化


120.X86平台上的I/O虚拟化

什么是虚拟化?抽象来说,虚拟化是资源的逻辑表示,它不受物理设备的约束。具体来说,虚拟化技术的实现形式是在系统中加入一个虚拟化层,虚拟化层将下层的资源抽象成另一种形式的资源,提供给上层使用。通过空间上的分割,时间上的分时以及模拟,虚拟化可以将一份资源抽象成多份。反过来说,虚拟化也可以将多份资源抽象成一份。总的来说,虚拟化抽象了硬件层,允许多种不同的负载能共享一组资源。在这样一个虚拟化的硬件平台上,各种工作能够使用相互隔离的资源并且共存,可以自由地进行资源跨平台的迁移,并且根据需要可以进行一些扩展性的应用。

虚拟化的好处是什么?各大企业和商业机构从虚拟化中可以得到非常大的效率提升,因为虚拟化可以显著提高服务器的使用率,能够进行动态分配、管理资源和负载的相互隔离,并提供高安全性和自动化。虚拟化还可以提供按需的服务配置和软件定义的资源编排,可以根据实际业务需求在云平台上扩展某类云服务。

如今,所有人都在谈论大数据和虚拟化,似乎虚拟化是最近几年才兴起的技术,而实际上,早在20世纪60年代,这个名称就已经诞生,在虚拟化技术不断发展的几十年历程中,它也经历了大起大落,只是因为技术尚未成熟而没有得到广泛的应用,但是随着近年来处理器技术和性能的的迅猛发展,虚拟化技术才真正显现出英雄本色,尤其是硬件虚拟化技术的诞生(例如Intel®VT技术),极大地扩展了虚拟化技术的应用范围(例如SDN/NFV领域)。

其中,I/O虚拟化是一个需要重点关注的地方,其接口选择、性能高低决定了该方案的成败。DPDK同样可以对I/O虚拟化助一臂之力。


121.X86平台虚拟化概述

虚拟化实现主要有三个部分的实现:CPU虚拟化、内存虚拟化和I/O虚拟化。Intel®为了简化软件复杂度、提高性能和增强安全性,对其IA架构进行扩展,提出了硬件辅助虚拟化技术VT-x和VT-d(详见[Ref10-1])。图10-1简单描述了Intel®的硬件辅助虚拟化技术。

图10-1 Intel®的硬件辅助虚拟化技术


122.CPU虚拟化

INTEL VT-x对处理器进行了扩展,引入了两个新的模式:VMX根模式和VMX非根模式(如图10-2所示)。宿主机运行所在的模式是根模式,客户机运行所在的模式是非根模式。

图10-2 支持Intel®VT-x技术的虚拟化架构

引入这两种模式可以很好地解决虚拟化漏洞的问题。通常,指令的虚拟化是通过陷入再模拟的方式实现的,而IA架构有多条敏感指令不能通过这种方法处理,否则会导致虚拟化漏洞。最直观的解决办法就是让这些敏感指令能够触发异常。非根模式下所有敏感指令的行为都被重新定义,使得它们能不经过虚拟化就直接运行或通过陷入再模拟的方式来处理,在根模式下,所有指令的行为和传统的IA一样,没有改变。

非根模式下敏感指令引起的陷入被称为VM-EXIT。当VM-Exit发生时,CPU自动从非根模式切换成为根模式,相应地,VT-x也定义了VM-Entry,该操作由宿主机发起,通常是调度某个客户机运行,此时CPU从根模式切换成为非根模式。

其次,为了更好地支持CPU虚拟化,VT-x引入了VMCS (Virtual-machine Control structure,虚拟机控制结构)。VMCS保存虚拟CPU需要的相关状态,例如CPU在根模式和非根模式下的特权寄存器的值。VMCS主要供CPU使用,CPU在发生VM-Exit和VM-Entry时都会自动查询和更新VMCS,以加速客户机状态切换时间。宿主机可以通过指令来配置VMCS,进而影响CPU的行为。


123.内存虚拟化

ARM SMMU原理与IOMMU技术(“VT-d” DMA、I/O虚拟化、内存虚拟化)

内存虚拟化的主要任务是实现地址空间的虚拟化,它引入了一层新的地址空间,即客户机物理地址空间。内存虚拟化通过两次地址转换来支持地址空间的虚拟化,即客户机虚拟地址GVA(Guest Virtual Address)→客户机物理地址GPA(Guest Physical Address)→宿主机物理地址HPA(Host Physical Address)的转换。其中,GVA→GPA的转换由客户机操作系统决定,通常是客户机操作系统通过VMCS中客户机状态域CR3指向的页表来指定;GPA→HPA的转换是由宿主机决定,宿主机在将物理内存分配给客户机时就确定了GPA→HPA的转换,宿主机通常会用内部数据结构来记录这个映射关系。

传统的IA架构只支持一次地址转换,即通过CR3指定的页表来实现虚拟地址到物理地址的转换,这和内存虚拟化所要求的两次地址转换产生了矛盾。为了解决这个问题,Intel VT-x提供了扩展页表(Extended Page Table, EPT)技术,直接在硬件上支持了GVA->GPA->HPA的两次地址转换,大大降低了内存虚拟化软件实现的难度,也提高了内存虚拟化的性能。

图10-3描述了EPT的基本原理。在原有的CR3页表地址映射的基础上,EPT引入了EPT页表来实现另一次映射。假设客户机页表和EPT页表都是4级页表,CPU完成一次地址转换过程如下。

❑CPU首先查找客户机CR3指向的L4页表。由于客户机CR3给出的是GPA,因此CPU需要通过EPT页表来实现客户机CR3 GPA—>HPA的转换。CPU首先会查看EPT TLB,如果没有对应的转换,CPU会进一步查找EPT页表,如果还没有,CPU则抛出异常由宿主机来处理。

❑在获得L4页表地址后,CPU根据GVA和L4表项的内容来获取L3页表的GPA。在获得L3页表的GPA后,CPU要通过查询EPT页表来实现L3 GPA→HPA的转换,过程和上面一样。

❑同样,CPU以这样的方式依次查找L2和L1页表,最后获得GVA对应的GPA,然后通过EPT页表获得HPA。

图10-3 EPT原理图

从上面的过程可以看出,CPU需要5次查询EPT页表,每次查询都需要4次EPT TLB或者内存访问,因此最坏情况下需要24次内存访问,这样的系统开销是很大的。EPT硬件通过增大EPT TLB来尽量减少内存访问。


124.I/O虚拟化

I/O虚拟化包括管理虚拟设备和共享的物理硬件之间I/O请求的路由选择。目前,实现I/O虚拟化有三种方式:I/O全虚拟化、I/O半虚拟化和I/O透传。它们在处理客户机和宿主机通信以及宿主机和宿主机架构上分别采用了不同的处理方式。

1. I/O全虚拟化

如图10-4a所示,该方法可以模拟一些真实设备。一个设备的所有功能或总线结构(如设备枚举、识别、中断和DMA)都可以在宿主机中模拟。客户机所能看到的就是一组统一的I/O设备。宿主机截获客户机对I/O设备的访问请求,然后通过软件模拟真实的硬件。这种方式对客户机而言非常透明,无需考虑底层硬件的情况,不需要修改操作系统。宿主机必须从设备硬件的最底层开始模拟,尽管这样可以模拟得很彻底,以至于客户机操作系统完全不会感知到是运行在一个模拟环境中,但它的效率比较低。

2. I/O半虚拟化

半虚拟化的意思就是说客户机操作系统能够感知到自己是虚拟机。如图10-4b中间所示,对于I/O系统来说,通过前端驱动/后端驱动模拟实现I/O虚拟化。客户机中的驱动程序为前端,宿主机提供的与客户机通信的驱动程序为后端。前端驱动将客户机的请求通过与宿主机间的特殊通信机制发送给后端驱动,后端驱动在处理完请求后再发送给物理驱动。不同的宿主机使用不同的技术来实现半虚拟化。比如说XEN,就是通过事件通道、授权表以及共享内存的机制来使得虚拟机中的前端驱动和宿主机中的后端驱动来通信。对于KVM使用virtio,和xen的半虚拟化网络驱动原理差不多,在第11章会有详细介绍。那么半虚拟化相对全虚拟化有什么好处?半虚拟化虽然和全虚拟化一样,都是使用软件完成虚拟化工作,但是机制不一样。在全虚拟化中是所有对模拟I/O设备的访问都会造成VM-Exit,而在半虚拟化中是通过前后端驱动的协商,使数据传输中对共享内存的读写操作不会VM-Exit,这种方式由于不像模拟器那么复杂,软件处理起来不至于那么慢,可以有更高的带宽和更好的性能。但是,这种方式与I/O透传相比还是存在性能问题,仍然达不到物理硬件的速度。

图10-4 I/O全虚拟化、I/O半虚拟化和I/O透传的设备模拟

3. I/O透传

直接把物理设备分配给虚拟机使用,例如直接分配一个硬盘或网卡给虚拟机,如图10-4c所示。这种方式需要硬件平台具备I/O透传技术,例如Intel VT-d技术。它能获得近乎本地的性能,并且CPU开销不高。

DPDK支持半虚拟化的前端virtio和后端vhost,并且对前后端都有性能加速的设计,这些将分别在后面两章介绍。而对于I/O透传,DPDK可以直接在客户机里使用,就像在宿主机里,直接接管物理设备,进行操作。


125.I/O透传虚拟化

I/O透传带来的好处是高性能,几乎可以获得本机的性能,这个主要是因为Intel®VT-d的技术支持,在执行IO操作时大量减少甚至避免VM-Exit陷入到宿主机中。目前只有PCI和PCI-e设备支持Intel®VT-d技术。它的不足有以下两点:

  • 1)x86平台上的PCI和PCI-e设备是有限的,大量使用VT-d独立分配设备给客户机,会增加硬件成本。
  • 2)PCI/PCI-e透传的设备,其动态迁移功能受限。动态迁移是指将一个客户机的运行状态完整保存下来,从一台物理服务器迁移到另一台服务器上,很快地恢复运行,用户不会察觉到任何差异。原因在于宿主机无法感知该透传设备的内部状态,因此也无法在另一台服务器恢复其状态。

针对这些不足的可能解决办法有以下几种:

  • 1)在物理主机上,仅少数对IO性能要求高的客户机使用VT-d直接分配设备,其他的客户机可以使用纯模拟或者virtio以达到多个客户机共享一个设备的目的。
  • 2)在客户机里,分配两个设备,一个是PCI/PCI-e透传设备,一个是模拟设备。DPDK通过bonding技术把这两个设备设成主备模式。当需要动态迁移时,通过DPDK PCI/PCI-e热插拔技术把透传设备从系统中拔出,切换到模拟设备工作,动态迁移结束后,再通过PCI/PCI-e热插拔技术把透传设备插入系统中,切换到透传设备工作。至此,整个过程结束。
  • 3)可以选择SR-IOV,让一个网卡生成多个独立的虚拟网卡,把这些虚拟网卡分配给每一个客户机,可以获得相对好的性能,但是这种方案也受限于PCI/PCIe带宽或者是SR-IOV扩展性的性能。

126.Intel®VT-d简介

ARM SMMU原理与IOMMU技术(“VT-d” DMA、I/O虚拟化、内存虚拟化)

在I/O透传虚拟化中,一个难点是设备的DMA操作如何直接访问到宿主机的物理地址。客户机操作系统看到的地址空间和宿主机的物理地址空间并不是一样的。当一个虚拟机直接和IO设备对话时,它提供给这个设备的地址是虚拟机物理地址GPA,那么设备拿着这个虚拟机物理地址GPA去发起DMA操作势必会失败。

该如何解决这个问题呢?办法是进行一个地址转换,将GPA转换成HPA主机物理地址,那么设备发起DMA操作时用的是HPA,这样就能拿到正确的地址。而Intel®VT-d就是完成这样的一个工作,在芯片组里引入了DMA重映射硬件,以提供设备重映射和设备直接分配的功能。在启用Intel®VT-d的平台上,设备所有的DMA传输都会被DMA重映射硬件截获,根据设备对应的IO页表,硬件可以对DMA中的地址进行转换,将GPA转换成HPA。其中IO页表是DMA重映射硬件进行地址转换的核心,它和CPU中的页表机制类似,IO页表支持4KB以及2MB和1GB的大页。VT-d同样也有IOTLB,类似于CPU的TLB机制,对DMA重映射的地址转换做缓存。如同第2章介绍的TLB和大页的原理一样,IOTLB支持2MB和1GB的大页,其对I/O设备的DMA性能影响很大,极大地减少了IOTLB失效(miss)。

VT-d技术还引入了域的概念,抽象地被定义为一个隔离的环境,宿主机物理内存的一部分是分配给域的。对于分配给这个域的I/O设备,那么它只可以访问这个域的物理内存。在虚拟化应用中,宿主机把每一个虚拟机当作是一个独立的域。图10-5a是没有VT-d,设备的DMA可以访问所有内存,各种资源对设备来说都是可见的,没有隔离,例如可以访问其他进程的地址空间或其他设备的内存地址。图10-5b是启用了VT-d,此时设备通过DMA重映射硬件只能访问指定的内存,资源被隔离到不同的域中,设备只能访问对应的域中的资源。详见[Ref10-2]。

图10-5 使用VT-d后访问内存架构

简单而言,VT-d主要给宿主机软件提供了以下的功能:

  • ❑I/O设备的分配:可以灵活地把I/O设备分配给虚拟机,把对虚拟机的保护和隔离的特性扩展到IO的操作上来。
  • ❑DMA重映射:可以支持来自设备DMA的地址翻译转换。
  • ❑中断重映射:可以支持来自设备或者外部中断控制器的中断的隔离和路由到对应的虚拟机。
  • ❑可靠性:记录并报告DMA和中断的错误给系统软件,否则的话可能会破坏内存或影响虚拟机的隔离。

127.PCIe SR-IOV概述

有了PCI/PCI-e透传技术,将物理网卡直接透传到虚拟机,虽然大大提高了虚拟机的吞吐量,但是一台服务器可用的物理网卡有限,如何才能实现水平拓展?因此,SR-IOV技术应运而生。

SR-IOV技术是由PCI-SIG制定的一套硬件虚拟化规范,全称是Single Root IO Virtualization(单根IO虚拟化)。SR-IOV规范主要用于网卡(NIC)、磁盘阵列控制器(RAID controller)和光纤通道主机总线适配器(Fibre Channel Host Bus Adapter, FC HBA),使数据中心达到更高的效率。SR-IOV架构中,一个I/O设备支持最多256个虚拟功能,同时将每个功能的硬件成本降至最低。SR-IOV引入了两个功能类型:

❑PF(Physical Function,物理功能):这是支持SR-IOV扩展功能的PCIe功能,主要用于配置和管理SR-IOV,拥有所有的PCIe设备资源。PF在系统中不能被动态地创建和销毁(PCI Hotplug除外)。

❑VF(Virtual Function,虚拟功能):“精简”的PCIe功能,包括数据迁移必需的资源,以及经过谨慎精简的配置资源集,可以通过PF创建和销毁。

如图10-6所示,SR-IOV提供了一块物理设备以多个独立物理设备(PF和VF)呈现的机制,以解决虚拟机对物理设备独占问题。每个VF都有它们自己的独立PCI配置空间、收发队列、中断等资源。然后宿主机可以分配一个或者多个VF给虚拟机使用。

图10-6 SR-IOV架构


128.PCIe网卡透传下的收发包流程

在虚拟化VT-x和VT-d打开的x86平台上,如果把一个网卡透传到客户机中,其收发包的流程与在宿主机上直接使用的一样,主要的不同在于地址访问多了一次地址转换。以DPDK收发包流程为例,在第6章已详细介绍了其DMA收发全景,如图10-7所示。

图10-7 网卡转发操作交互示意图

  • 1. CPU填充缓冲地址到接收侧描述符
  • 2. 网卡读取接收侧描述符获取缓冲区地址
  • 3. 网卡将包的内容写到缓冲区地址处
  • 4. 网卡回写接收侧描述符更新状态(确认包内容已写完)
  • 5. CPU读取接收侧描述符以确定包接收完毕
  • 6. CPU读取包内容做转发判断
  • 7. CPU填充更改包内容,做发送准备
  • 8. CPU读发送侧描述符,检查是否有发送完成标志
  • 9. CPU将准备发送的缓冲区地址填充到发送侧描述符
  • 10. 网卡读取发送侧描述符中地址
  • 11. 网卡根据描述符中地址,读取缓冲区中数据内容
  • 12. 网卡写发送侧描述符,更新发送已完成标记

 

其中步骤1、5、6、7、8、和9是需要CPU对内存的操作。在虚拟化下,在对该内存地址的第一次访问,需要进行两次地址转换:客户机的虚拟地址转换成客户机的物理地址,客户机的物理地址转换成宿主机的物理地址。这个过程和网卡直接在宿主机上使用相比,多了一次客户机的物理地址到宿主机的物理地址的转换,这个转换是由Intel®VT-x技术中的EPT技术来完成。这两次的地址转换结果会被缓存在CPU的Cache和TLB中。对该内存地址的再次访问,如果命中CPU的cache或TLB,则无需进行两次地址转换,其开销就很小了;如果不命中,则还需重新进行两次地址转换。

剩下的步骤都是网卡侧发起的操作,也需要对内存操作。在非虚拟化下,宿主机里的网卡进行操作时,无论DMA还是对描述符的读写,直接用的就是物理地址,不需要地址转换。在虚拟化下,在对该内存地址的第一次访问,需要进行一次地址转换,客户机的物理地址转换成宿主机的物理地址。同直接在宿主机上使用相比,多了这一次地址转换,这个转换是由Intel®VT-d技术的DMA重映射来完成。这个地址转换结果会被缓存在VT-d的IOTLB中。对该内存地址的再次访问,如果命中IOTLB,则无需进行地址转换,其开销就小;如果不命中,则还需再次做地址转换。为了增加IOTLB命中的概率,建议采用大页。详见[Ref10-3]。


129.I/O透传虚拟化配置的常见问题

问题1:Intel®的服务器,BIOS打开VT-x和VT-d,想把一个PCIe网卡透传到虚拟机中,发现虚拟机启动失败,提示IOMMU没有找到。

解答:不仅要在BIOS设置上打开VT-d,还要在Linux内核启动选项中设置intel_iommu=on。有些Linux内核版本可能缺省没有使能CONFIG_INTEL_IOMMU。

问题2:Intel®的服务器,BIOS打开VT-x和VT-d, Linux内核启动参数有intel_iommu=on,但想在宿主机上运行DPDK程序。把主机上网卡端口绑定到igb_uio驱动,然后运行DPDK程序,会遇到错误,dmesg会报DMAR错误,如“dmar: DMAR:[DMA Read] Request device [07:00.1] fault addr 1f73220000”。

解答:两个解决办法。如果还需要使用VT-d透传技术把另一个PCI/PCI-e设备分配给虚拟机,则在内核启动参数中设置iommu=pt。“iommu=pt”会让主机内核跳过地址的翻译(绕过VT-d),直接使用程序给的地址来做DMA,不需要查询IO页表做地址翻译,这样的设置不会影响虚拟机的DMA重映射。如果系统不需要使用VT-d透传技术分配一个PCI/PCI-e设备给虚拟机,则可以在BIOS中关闭VT-d,或把内核启动参数intel_iommu=on改为intel_iommu=off。

问题3:在与问题2同样的配置环境下,不过在主机上把网卡端口绑定到vf io-pci驱动,而不是igb_uio驱动,然后运行DPDK程序,结果程序能够正常运行。这里也没有设置iommu=pt,为什么又可以工作了呢?

解答:VFIO是一个IOMMU的用户态驱动,它可以在用户态配置IOMMU。当使用vf io驱动时,DPDK会设置DMA映射,直接把物理地址作为DMA的地址,这样就不需要查询页表做地址翻译。而igb_uio如果不直接配置IOMMU,就绕不过去IOMMU的地址翻译。如果读者想更多了解VFIO,可以自行翻阅资料。


130.小结

本章主要讲解x86平台上的虚拟化技术,从CPU/内存/I/O虚拟法实现的角度,介绍了Intel的硬件辅助解决方案;着重介绍了I/O透传虚拟化技术,VT-d和SR-IOV;最后结合DPDK的问题和应用,了解虚拟化中的DPDK和本机DPDK的主要不同。


系列文章

《深入浅出DPDK》读书笔记(一):基础部分知识点

《深入浅出DPDK》读书笔记(二):网卡的读写数据操作

《深入浅出DPDK》读书笔记(三):NUMA - Non Uniform Memory Architecture 非统一内存架构

《深入浅出DPDK》读书笔记(四):并行计算-SIMD是Single-Instruction Multiple-Data(单指令多数据)

《深入浅出DPDK》读书笔记(五):同步互斥机制

《深入浅出DPDK》读书笔记(六):报文转发(run to completion、pipeline、精确匹配算法、最长前缀匹配LPM)

《深入浅出DPDK》读书笔记(七):PCIe与包处理I/O

《深入浅出DPDK》读书笔记(八):网卡性能优化(异步中断模式、轮询模式、混和中断轮询模式)

《深入浅出DPDK》读书笔记(九):流分类与多队列

《深入浅出DPDK》读书笔记(十):硬件加速与功能卸载(VLAN、IEEE1588、IP TCP/UDP/SCTP checksum、Tunnel)

《深入浅出DPDK》读书笔记(十一):DPDK虚拟化技术篇(I/O虚拟化、CPU虚拟化、内存虚拟化、VT-d、I/O透传)

 


相关阅读

DPDK PMD( Poll Mode Driver)轮询模式驱动程序

DPDK笔记 RSS(receive side scaling)网卡分流机制

网卡多队列:RPS、RFS、RSS、Flow Director(DPDK支持)

Linux环境中的网络分段卸载技术 GSO/TSO/UFO/LRO/GRO

ARM SMMU原理与IOMMU技术(“VT-d” DMA、I/O虚拟化、内存虚拟化)

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 酷酷鲨 设计师:CSDN官方博客 返回首页