0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

DPDK内存管理的IOMMU和IOVA技术总结

454398 来源: Chinaunix 作者:lvyilong316 2020-09-25 15:16 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

之前写过DPDK相关内存管理的代码分析,但是随着DPDK的版本迭代在内存管理方面也在进行着不断的演进。这里结合一些参考文章再对DPDK的内存使用方式和发展变化做一个阶段性的总结。

大页

DPDK通常是使用大页(hugepage)内存的,无论是2M的大页还是1G的大页,本质上都是为了减少TLB miss,通过更大的page size来提升TLB的命中率,而TLB就是用来缓存页表的高速缓存。

DMA

我们知道计算机的设备,如网卡硬件是不能处理用户空间的虚拟地址(只有CPU通过页表转换MMU才能识别虚拟地址),因为它不能感知任何用户态的进程和其所分配到的用户空间虚拟地址。相反,它只能访问真实的物理地址上的内存。

出于对效率的考量,现代硬件几乎总是使用直接内存存取(DMA)事务。通常,为了执行一个DMA事务,内核需要参与创建一个支持DMA的存储区域,将进程内虚拟地址转换成硬件能够理解的真实物理地址,并启动DMA事务。这是大多数现代操作系统中输入输出的工作方式;然而,这是一个耗时的过程,需要上下文切换、转换和查找操作,这不利于高性能输入/输出。

DPDK的内存管理以一种简单的方式解决了这个问题。每当一个内存区域可供DPDK使用时,DPDK就通过询问内核来计算它的物理地址,即DPDK维护了虚拟地址和物理地址的一个映射关系,由于DPDK使用锁定(如vfio_pin_map_dma)内存(防止物理内存和虚拟内存的映射关系变化),来使底层内存区域的物理地址不会改变,因此硬件可以依赖这些物理地址始终有效,即使内存本身有一段时间没有使用。然后,DPDK会在准备由硬件完成的输入/输出事务时使用这些物理地址,并以允许硬件自己启动DMA事务的方式配置硬件。这使DPDK避免不必要的开销,并且完全从用户空间执行输入/输出。

IOMMU和IOVA

默认情况下,任何硬件都可以访问整个系统的物理内存,因此它可以在任何地方执行DMA事务。这有许多安全隐患。例如,流氓和/或不可信进程(包括在VM (虚拟机)内运行的进程)可能使用硬件设备来读写内核空间,和几乎其他任何存储位置。为了解决这个问题,现代系统配备了输入输出内存管理单元(IOMMU)。这是一种硬件设备,提供DMA地址转换和设备隔离功能,因此只允许特定设备执行进出特定内存区域(由IOMMU指定)的DMA事务,而不能访问指定访问之外的系统内存地址空间。

由于IOMMU的参与,硬件使用的物理地址可能不是真实的物理地址,而是IOMMU分配给硬件的(完全任意的)输入输出虚拟地址(IOVA)。一般来说,DPDK社区可以互换使用物理地址和IOVA这两个术语,但是根据上下文,这两者之间的区别可能很重要。例如,DPDK 17.11和更新的DPDK长期支持(LTS)版本在某些情况下可能根本不使用实际的物理地址,而是使用用户空间虚拟地址来实现DMA。IOMMU负责地址转换,因此硬件永远不会注意到两者之间的差异。

如上图所示,P1和P2进程分别用虚拟地址P进行DMA,由于IOMMU将虚拟地址P映射到不同的物理地址,所以这并不会冲突,而P3访问的地址P并没有在IOMMU中建立映射关系,所以DMA访问会导致失败。

IO虚拟地址(IOVA)模式

DPDK是一个用户态应用框架,使用DPDK的软件可以像其他软件一样使用常规虚拟地址。但除此之外,DPDK还提供了用户态PMD和一组API,以实现完全以用户态执行IO操作。前文也已经提到过,硬件不能识别用户空间虚拟地址;它使用的是IO地址——物理地址(PA)或IO虚拟地址(IOVA)。

DPDK API对物理和IO虚拟地址不作区分,即使不是由IO内存管理单元(IOMMU)提供VA部分,也都以IOVA来代表两种地址。但DPDK却会区分物理地址作为IOVA的情况,和用户空间虚拟地址作为IOVA的情况。它们在DPDK API中被称为IOVA模式,可分为两种:PA作为IOVA模式,和VA作为IOVA模式。

PA作为IOVA模式

PA作为IOVA的模式下,分配到整个DPDK存储区的IOVA地址都是实际的物理地址,而虚拟内存的分配与物理内存的分配相匹配。该模式的一大优点就是它很简单:它适用于所有硬件(也就是说,不需要IOMMU),并且它适用于内核空间(将真实物理地址转换为内核空间地址的开销是微不足道的)。实际上,这就是DPDK长期以来的运作方式,在很多方面它都被认为是默认的选项。

然而,作为PA的IOVA模式也存在一些缺点。其中一个就是它需要根用户特权——如果无法访问系统的页面映射(因为DPDK要维护虚拟地址和物理地址IOVA的对应关系),DPDK就无法获取内存区域的真实物理地址。因此,如果系统中没有root权限,就无法以该模式运行。

PA作为IOVA的模式

PA作为IOVA的模式还有另外一个值得一提的限制——虚拟内存分配要遵循物理内存分配。这意味着如果物理内存空间被分段(被分成许多小段而不是几个大段)时,虚拟内存空间也要遵循同样的分段。极端情况下,分段可能过于严重,导致被分割出来物理上连续的片段数量过多,耗尽DPDK用于存储这些片段相关信息的内部数据结构,就会让DPDK初始化失败

作为PA的IOVA模式下PA分段示例。

应对这些问题,DPDK社区提出了解决方法。举例来说,一种减少分段影响的方式是使用更大的分页——问题虽然没被解决,但是单独的1千兆字节(GB)段比独立的2兆字节(MB)段能大幅度减小分段的数量。另外一种广泛使用的解决方式则是在启动时引导系统并保留大页,而不是在运行时。但上述的解决方法都不能根本地解决问题,而且整个DPDK社区都习惯了要去解决这些问题,每个DPDK用户(有意或无意)在使用时都会采取相同的思维模式——“我需要X MB内存,但以防万一,我要保留X + Y MB!”

VA作为IOVA模式

相比之下,VA作为IOVA的模式不需遵循底层物理内存的分布。而是重新分配物理内存,与虚拟内存的分配匹配。DPDK EAL依靠内核基础设施来实现这一点。内核基础设施又反过来使用IOMMU重新映射物理内存。

作为VA的IOVA模式。

这种方式的优点显而易见:VA作为IOVA的模式下,所有内存都是VA和IOVA连续的。这意味着所有需要大量IOVA连续内存的内存分配更有可能成功,因为对硬件来说,即使底层物理内存可能不存在,内存看上去还是IOVA连续的。由于重新映射,IOVA空间片段化的问题就变得无关紧要。不管物理内存被分段得多么严重,它总能被重新映射为IOVA-连续的大块内存。

作为VA的IOVA模式下的分段示例。

VA作为IOVA的模式还有另一个优点,它不需要任何权限。这是因为它不需要访问系统页面映射。这样就可以允许以非root用户身份运行DPDK,而且在特权访问不受欢迎的环境中,如云原生环境就可以更加容易地使用DPDK。

当然,作为VA的IOVA模式也有一个缺点。出于各种原因,有时候可能不能选择使用IOMMU。这种情况可能包括:

1)硬件不支持IOMMU;

2)平台可能本身就没有IOMMU(比如没有IOMMU模拟的VM);

3)软件设备(例如,DPDK的内核网络接口(KNI)PMD)不支持作为VA的IOVA模式;

4)一些IOMMU(通常是模拟的IOMMU)的地址宽度可能有限,虽然这不妨碍用作VA的IOVA模式,但限制了其有效性;

5)在非Linux *的操作系统上使用DPDK;

但是,这些情况还是相对较少,绝大多数情况下,VA作为IOVA的模式都可以正常工作。

IOVA模式的选择

很多情况下,DPDK默认选择作为PA的IOVA模式,因为从硬件角度这是最安全的模式。所有给定的硬件(或软件)PMD至少都可以保证支持作为PA的IOVA模式。尽管如此,如果条件允许,还是强烈建议所有DPDK用户使用作为VA的IOVA模式,毕竟此模式具有不可否认的优势。

但是,用户不必非要在两者中选择一个。可以自动检测出最合适的IOVA模式,而且默认选项绝对适用于大多数情况,因此不需要用户来做此选择。如果默认选项并不合适,用户可以使用--iova-mode EAL命令行参数尝试使用EAL标志(适用于DPDK 17.11及更高版本)来代替IOVA模式:

1./app --iova-mode=pa # use IOVA as PA mode

2./app --iova-mode=va # use IOVA as VA mode

大多数情况下,VA和PA模式不会互相排斥,可以使用任一模式,但在某些情况下,PA作为IOVA的模式是唯一可用的选择。当不能使用作为VA模式的IOVA时,即使EAL参数要求使用作为VA模式的IOVA,DPDK也会自动切换为作为PA模式的IOVA。DPDK还提供了一个API,可查询运行时正在使用的IOVA模式,但通常这不会在用户应用中使用,因为只有像是DPDK PMD和总线驱动程序才会要求获取这种信息。

UIO和VFIO对IOVA的支持

lIgb_uio

DPDK代码库中最早的内核驱动程序是igb_uio驱动程序。在DPDK最初的发展阶段,这个驱动程序就已经存在了,因此它是DPDK开发人员使用最广泛也是最熟悉的驱动程序。

此驱动程序依赖内核用户空间IO(UIO)基础结构运作,并为所有中断类型(INT、消息信号中断(MSI)和MSI-X)提供支持,以及创建虚拟功能。它还公开硬件设备通过/dev/uio文件系统注册和中断句柄,然后DPDK EAL将它们用于将它们映射到用户空间并使它们可用于DPDK PMD。

gb_uio驱动程序非常简单,能做的也并不多,因此它不支持使用IOMMU。或者,更确切地说,它确实支持IOMMU,但仅在传输模式下,它在IOVA和物理内存地址之间建立1:1映射。igb_uio不支持使用完整的IOMMU模式。因此,igb_uio驱动程序仅支持PA作为IOVA模式,并且根本无法在IOVA中作为VA模式工作

类似于igb_uio的驱动程序在内核中可用:uio_pci_generic。它的工作方式与igb_uio非常相似,只是它的功能更加有限。例如,igb_uio支持所有中断类型(传统,MSI和MSI -X),而uio_pci_generic只支持传统中断。更重要的是,igb_uio可以创建虚拟函数(Virtual Function, VF),而uio_pci_generic则不能;因此,如果在使用DPDK物理函数(Physical Function, PF)驱动程序时创建VF是必需的一步,igb_uio是唯一的选择。

因此,在大多数情况下,igb_uio与uio_pci_generic相同或更可取。关于使用IOMMU的所有限制同样适用于igb_uio和uio_pci_generic驱动程序-它们不能使用完整的IOMMU功能,因此仅支持IOVA作为PA模式。

lvfio

vfio-pci驱动是虚拟功能I / O(VFIO)内核基础结构的一部分,并在Linux 3.6版中引入。VFIO使设备寄存器和设备中断可供用户空间应用程序使用,并可使用IOMMU设置IOVA映射以从用户空间执行IO。后一部分至关重要,此驱动程序专为与IOMMU一起使用而开发,在较旧的内核上,如果没有启用IOMMU,它甚至都无法工作。

与直观看法相反,使用VFIO驱动程序允许使用PA作为IOVAVA作为IOVA模式。这是因为,虽然建议使用IOVA作为VA模式来利用该模式的所有好处,但没有什么能阻止DPDK的设置IOMMU映射的EAL以遵循物理内存布局1:1的方式;毕竟IOVA映射是任意的。在这种情况下,即使使用IOMMU,DPDK也可以在IOVA中作为PA模式工作,从而允许DPDK KNI等工作。但是,仍然需要root权限才能将IOVA用作PA模式。

在更新的内核(4.5+,向后移植到一些旧版本)上,有一enable_unsafe_noiommu_mode选项,允许在没有IOMMU的情况下使用VFIO。这种模式适用于与基于UIO的驱动程序相同的所有意图和目的,并具有所有相同的优点与限制。

17.11及早期版本

使用DPDK库17.11版本或更早版本的任何应用程序必须事先知道其内存要求。这是因为,对于这些版本的DPDK,在初始化之后不可能再申请额外的大页内存,或者将其释放回系统。因此,DPDK应用程序可能使用的任何内存都必须在应用程序初始化时预留,并在应用程序的整个生命周期都由DPDK保留。

在决定要保留的内存量时,留出一些余量通常是个好主意。在各种内部分配中,某些DPDK内存将在不同的内部分配中被“浪费”,数量会因您的配置而异(DPDK将使用的设备数量,启用功能等)。

此外,DPDK17.11中的大多数API都需要大量的IOVA连续内存。这是因为在DPDK 17.11中,虚拟内存布局总是与物理内存布局相匹配。换句话说,如果使用PA作为IOVA,则要求PA是连续的。这是DPDK17.11内存管理中众所周知的问题之一:实际上很少有应用程序需要PA连续内存,由于缺少足够的IOVA连续内存,分配大量内存可能会失败。

IOVA模式的比较

上述限制当然仅适用于作为物理地址(PA)模式的IOVA,因为在该模式下,DPDK的虚拟地址(VA)空间遵循PA空间的布局。在PA模式的IOVA中,可用IOVA连续内存量取决于DPDK控制之外的许多因素,尽管DPDK将尝试保留尽可能多的IOVA连续内存,具体取决于可用内存量和系统配置,可能没有足够的IOVA连续内存来满足所有分配。

在VA模式的IOVA中,这不是问题,因为在这种情况下,IOVA空间布局将与VA空间的布局相匹配(而不是相反),并且所有物理内存都被重新映射为IOVA连续到硬件。

18.11及之后版本

动态内存管理

DPDK 18.11的最大变化是可以在运行时增加和减少内存使用量,从而消除了DPDK内存映射为静态的情况,这带来了许多可用性方面的改进。

在DPDK 17.11中,运行没有任何环境抽象层(EAL)参数的DPDK应用会保留所有可用的大页内存供其使用,且不会为其他应用程序或其他DPDK实例留下任何大页内存。对于DPDK18.11而言情况有所不同,DPDK仅保留应用运行所必须的内存量。在这种意义上,DPDK现在性能更好,并且使DPDK与其他应用程序完美配合所需的工作也更少。

同样,不再需要事先知道应用程序的内存需求,DPDK的内存映射可以动态增加和减少,因此DPDK内存子系统可以根据需要自动增加其内存使用量,并在不再需要时将内存返回给系统。这意味着部署DPDK应用程序所需的工作更少,因为现在DPDK可以自行管理其内存需求。
DPDK 18.11和IOVA连续性

DPDK 18.11中的一项基本后台更改是,不能保证虚拟地址(VA)连续内存是IOVA连续的;两者之间不再有任何关联。在VA作为IOVA的模式下,IOVA布局仍然像以前一样遵循VA布局,但是在PA作为IOVA的模式下,PA布局是任意的(物理页面要向后映射并不罕见)

DPDK版本之间的IOVA(PA模式)布局比较

这种改变并不像看起来那样具有颠覆性,因为实际上没有多少数据结构需要IOVA连续内存。所有软件数据结构(环,内存池,哈希表等)仅需要VA连续内存,而不在意底层物理内存布局。这使得在早期DPDK版本上工作的大多数用户应用程序可以无缝过渡到新版本,而无需更改代码。

尽管如此,某些数据结构确实需要IOVA连续内存(例如,硬件队列结构),对于这些情况,引入了新的分配器标志。使用此标志,可以使memzone分配器尝试分配IOVA连续的内存。

单个文件段

较旧的DPDK版本在hugetlbfs文件系统中的每个大页上存储一个文件,这适用于大多数用例,但有时会出现问题,特别是,vhost-user后端的Virtio将与后端共享文件,并且有可共享文件描述符数量的硬性限制。当使用大页(例如1 GB的页面)时,它可以很好地工作,但是在页面大小较小的情况下,文件数量会很快超过文件描述符限制。

为了解决此问题,版本18.11中引入了一种新模式,即单文件段模式,该模式通过--single-file-segmentsEAL命令行标志启用,这使得EAL在hugetlbfs中创建的文件更少,并且使具有vhost-user后端的Virtio甚至可以在最小页面大小下工作。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 寄存器
    +关注

    关注

    31

    文章

    5589

    浏览量

    129058
  • dma
    dma
    +关注

    关注

    3

    文章

    577

    浏览量

    105352
  • 动态内存管理

    关注

    0

    文章

    5

    浏览量

    6731
  • 物理内存
    +关注

    关注

    0

    文章

    11

    浏览量

    8643
  • DPDK
    +关注

    关注

    0

    文章

    14

    浏览量

    1946
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    WebGL/Canvas 内存泄露分析

    在构建高性能、长周期运行的 WebGL/Canvas 应用(如 3D 编辑器、数据可视化平台)时,内存管理是一个至关重要且极具挑战性的课题。 开发者通常面临的内存泄漏问题,其根源远比简单
    的头像 发表于 10-21 11:40 167次阅读
    WebGL/Canvas <b class='flag-5'>内存</b>泄露分析

    科普:什么AI 内存技术

    AI 内存是一种专为人工智能 (AI) 应用设计的新型内存技术。与传统的通用内存(如 DDR5 或 LPDDR5)不同,AI 内存的核心目标
    的头像 发表于 09-03 15:44 719次阅读

    灵活高效ZBUFF — C内存数据操作库:优化内存管理的利器

    在C语言开发中,高效的内存管理是提升程序性能的关键。ZBUFF作为一款灵活高效的内存数据操作库,通过优化内存分配与释放机制,为开发者提供了更简洁、更安全的API接口,极大地简化了复杂数
    的头像 发表于 08-14 18:01 519次阅读
    灵活高效ZBUFF — C<b class='flag-5'>内存</b>数据操作库:优化<b class='flag-5'>内存</b><b class='flag-5'>管理</b>的利器

    免费分享:一个低成本8电1光+5G|+WI-FI6+ SATA3.0+DPDK融合网关方案

    本帖最后由 jf_83141691 于 2025-7-21 17:59 编辑 硬件特色:1、RK3568 4核2.0G CPU主控方案,默认8G内存,16G板载存储;2、RTL8370M三层
    发表于 07-21 17:56

    CES Asia 2025同期低空智能感知与空域管理技术论坛即将启幕

    在低空经济蓬勃发展的大背景下,CES Asia 2025亚洲消费电子展备受瞩目,同期举办的低空智能感知与空域管理技术论坛更是引发行业内外高度关注。此次论坛聚焦低空通信导航监视技术、无人机反制与空域
    发表于 07-10 10:16

    替代专用硬件!一文梳理开源VPP+DPDK技术和产业界应用实例

    VPP 这一开源技术在通用 CPU 的基础上,实现了传统上需要专门的网络硬件设备(如路由器)和专业的网络操作系统才能达到的性能,以极高的性价比为广大用户带来了开放网络技术的红利。VPP 集成了DPDK项目,通过它直接访问硬件网卡
    的头像 发表于 07-07 17:17 1167次阅读
    替代专用硬件!一文梳理开源VPP+<b class='flag-5'>DPDK</b><b class='flag-5'>技术</b>和产业界应用实例

    工业APP频繁崩溃?聚徽厂家分享安卓工控机内存碎片化与进程管理优化指南

    与进程管理两大核心维度,深入剖析崩溃根源,并提出系统性优化方案。 一、内存碎片化:工业APP崩溃的隐形推手 1. 内存碎片化的成因与危害 内存碎片化是指
    的头像 发表于 06-10 10:24 360次阅读

    HarmonyOS优化应用内存占用问题性能优化四

    一、使用purgeable优化C++内存 Purgeable Memory是HarmonyOS中native层常用的内存管理机制,可用于图像处理的Bitmap、流媒体应用的一次性数据、图片等
    发表于 05-24 17:20

    HarmonyOS优化应用内存占用问题性能优化一

    应用开发过程中注重内存管理,积极采取措施来减少内存占用,以优化应用程序的性能和用户体验。 HarmonyOS提供了一些内存管理的工具和接口,
    发表于 05-21 11:27

    IEC61508系统中的动态内存使用

    IEC 61508标准强烈推荐使用静态内存管理方式。在安全应用设计中,我们都在遵循这个建议。
    的头像 发表于 04-11 15:17 1200次阅读
    IEC61508系统中的动态<b class='flag-5'>内存</b>使用

    HBM新技术,横空出世:引领内存芯片创新的新篇章

    随着人工智能、高性能计算(HPC)以及数据中心等领域的快速发展,对内存带宽和容量的需求日益增长。传统的内存技术,如DDR和GDDR,已逐渐难以满足这些新兴应用对高性能、低延迟和高能效的严苛要求。正是
    的头像 发表于 03-22 10:14 3154次阅读
    HBM新<b class='flag-5'>技术</b>,横空出世:引领<b class='flag-5'>内存</b>芯片创新的新篇章

    快速搞懂C语言程序内存分区!

    在程序运行过程中,操作系统会根据程序的需要,将内存划分为多个功能不同的区段,以便更高效地管理内存资源和确保程序的稳定运行。不同的内存区段负责存储不同类型的数据和代码,涵盖了从程序指令、
    的头像 发表于 03-14 17:37 1334次阅读
    快速搞懂C语言程序<b class='flag-5'>内存</b>分区!

    Xmind完成对AI总结工具Briefy的战略收购

    全球知名的知识管理企业Xmind近日宣布,已完成对AI总结工具Briefy的战略收购。Briefy以其强大的大语言模型驱动的多模态解析技术著称,能够将长视频和万字文档等复杂信息转化为结构清晰的大纲或思维导图,并通过知识库功能帮助
    的头像 发表于 02-13 16:01 833次阅读

    hyper v 内存,hyper v 内存设置的操作步骤和方法是什么?

    在利用Hyper-V搭建和管理虚拟机的过程中,合理设置虚拟机的内存至关重要。内存分配是否恰当,会直接影响到虚拟机的运行性能和稳定性。若内存分配过少,虚拟机可能运行缓慢甚至频繁卡顿;而分
    的头像 发表于 01-24 15:22 1092次阅读
    hyper v <b class='flag-5'>内存</b>,hyper v <b class='flag-5'>内存</b>设置的操作步骤和方法是什么?

    hyper 内存,Hyper内存:如何监控与优化hyper-v虚拟机的内存使用

    在日常工作中,我们常常需要处理大量的文件和数据,这些重复性任务不仅耗时耗力,还容易因疲劳而导致错误。幸运的是,批量管理工具的出现为这一问题提供了高效的解决方案。今天就为大家介绍Hyper内存
    的头像 发表于 01-24 14:15 1672次阅读
    hyper <b class='flag-5'>内存</b>,Hyper<b class='flag-5'>内存</b>:如何监控与优化hyper-v虚拟机的<b class='flag-5'>内存</b>使用