当前位置:数码通 > 动态

DPDK如何处理物理内存

来源于 数码通 2023-10-05 16:29

本文将介绍几种可用的不同配置选项,并为读者未来的选择提供建议。

环境抽象层 (EAL) 参数

环境抽象层(EAL)是DPDK的核心。它是DPDK的一个库。顾名思义,它负责抽象出环境(硬件操作系统等),并为软件提供统一的接口。 EAL要处理很多事情,所以不难理解为什么它是DPDK中最复杂的部分。 EAL 处理的事情包括:

· 管理 CPU 核心和非均匀内存访问 (NUMA) 节点

· 将硬件设备的寄存器映射到内存中,以便它们可以由DPDK轮询模式驱动程序(PMD)驱动

· 管理硬件​​和软件中断

· 抽象平台差异,例如字节顺序、缓存行大小等。

· 管理内存和多进程同步

· 提供原子、内存屏障和其他同步原语通用的独立于平台和操作系统的方法

· 加载和枚举硬件总线、设备和 PMD

上面只列出了EAL的部分功能,但这足以体现其对于DPDK的重要性。因此,DPDK中大量配置与EAL相关也就不足为奇了。目前,可以通过为 DPDK 初始化例程指定命令行参数来配置(直接或间接)EAL。 DPDK应用程序命令行通常如下所示:

./app --

某些使用 DPDK(例如 OvS-DPDK)的应用程序可能会对用户隐藏此步骤,因此可能不需要显式指定 EAL 命令行参数,但此步骤仍然会在后台发生。

IO 虚拟地址 (IOVA) 模式

DPDK是一个用户模式应用程序框架。使用DPDK的软件可以像其他软件一样使用常规虚拟地址。但除此之外,DPDK还提供了用户态PMD和一组API来完全在用户态下实现IO操作。正如本系列上一篇文章中提到的,硬件无法读取用户空间虚拟地址;它使用 IO 地址 - 物理地址 (PA) 或 IO 虚拟地址 (IOVA)。

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

IOVA 模式作为物理地址 (PA)

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

然而,IOVA模型作为PA也存在一些缺点。一是它需要root用户权限——在无法访问系统的页面映射的情况下,DPDK无法获取内存区域的真实物理地址。因此,如果系统中没有 root 权限,则无法在此模式下运行。

图 1. 作为 PA 的 IOVA 模型。

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

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

针对这些问题,DPDK社区提出了解决方案。例如,减少碎片影响的一种方法是使用更大的分页 - 问题并未解决,但单独的 1 GB 段的性能比单独的 2 兆字节 (MB) 段更好。大幅减少段数。另一种广泛使用的解决方案是引导系统并在启动时而不是运行时保留大页面。但以上方案都不能从根本上解决问题,整个DPDK社区都在用来解决这些问题。每个DPDK用户(有意无意)在使用时都会采取相同的思维模式——“我需要X MB RAM,但我保留X + Y MB以防万一!”

IOVA 模式作为虚拟地址 (VA)

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

图 3. IOVA 模型为 VA。

这种方法的优点是显而易见的:在作为 VA 的 IOVA 模式下,所有内存都是 VA 和 IOVA 连续的。这意味着所有需要大量 IOVA 连续内存的内存分配更有可能成功,因为对于硬件而言,即使底层物理内存可能不存在,内存也会显示为 IOVA 连续。由于重新映射,IOVA 空间碎片问题变得无关紧要。无论物理内存的分段程度如何,它始终可以重新映射为 IOVA 连续的内存块。

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

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

当然,IOVA模型作为VA也有一个缺点。由于各种原因,有时可能无法选择使用 IOMMU。这可能包括:

· 硬件不支持IOMMU

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

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

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

· 在 Linux* 以外的操作系统上使用 DPDK

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

选择IOVA模式

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

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

1./app --iova-mode=pa # 使用 IOVA 作为 PA 模式

2./app --iova-mode=va # 使用 IOVA 作为 VA 模式

在大多数情况下,VA 和 PA 模式并不相互排斥,可以使用任一模式,但在某些情况下,IOVA 作为 PA 模式是唯一可用的选项。当无法使用 IOVA 作为 VA 模式时,即使 EAL 参数要求使用 IOVA 作为 VA 模式,DPDK 也会自动切换到 IOVA 作为 PA 模式。

DPDK 还提供了一个 API 来查询运行时使用的 IOVA 模式,但通常不会在用户应用程序中使用,因为只有 DPDK PMD 和总线驱动程序会询问此信息。

IOVA 模式和 DPDK PCI 驱动程序

DPDK本身并不执行所有硬件设备寄存器和中断映射,它需要内核的帮助。为此,DPDK 使用的所有硬件设备都需要绑定到通用外围组件互连 (PCI) 内核驱动程序。与通用设备内核驱动程序不同,该通用驱动程序不锁定到特定的 PCI ID 集,即针对某种类型设备的通用驱动程序,可以与任何类型的 PCI 设备一起使用。

要将设备绑定到通用驱动程序,DPDK 用户应参阅 DPDK 文档。本文档描述了如何在所有支持的操作系统中执行此操作。不过,还是有必要解释一下DPDK支持的各种用户态IO驱动以及它们支持的IOVA模式。虽然内核驱动程序和支持的 IOVA 模式之间似乎存在 1:1 的对应关系,但事实并非如此。以下部分讨论 Linux 上可用的驱动程序。

用户空间 IO (UIO) 驱动程序

DPDK 代码库中最古老的内核驱动程序是 igb_uio 驱动程序。该驱动自DPDK开发初期就已存在,因此是DPDK开发者使用最广泛、最熟悉的驱动。

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

igb_uio 驱动程序非常简单并且没有做太多事情,因此它不支持使用 IOMMU 也就不足为奇了。或者更确切地说,它确实支持 IOMMU,但仅在传输模式下,它在 IOVA 和物理内存地址之间创建 1:1 映射。 igb_uio 不支持使用完整的 IOMMU 模式。因此,igb_uio 驱动程序仅支持 IOVA 作为 PA 模式,并且在 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物理功能(PF)驱动程序时创建VF,这是必需的步骤,igb_uio是唯一的选择。

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

VFIO 内核驱动

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

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

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

内核驱动选择

一般来说,从应用程序的角度来看,我们不需要选择内核驱动程序。一般来说,内核驱动的选择要根据具体情况来确定。下面的流程图可以帮助决定在特定情况下使用哪个驱动程序:

图 5. 通用 PCI 内核驱动程序选择流程图。

如图 5 所示,显然 VFIO 驱动程序应该在几乎所有情况下使用,尤其是在生产环境中。 IOMMU可以提供硬件层面的设备隔离,这可以让使用DPDK的应用程序更加安全,而IOVA模式作为VA可以通过重映射更好地利用内存,并且不需要root权限来运行DPDK应用程序。但是,某些用例需要 igb_uio 或 uio_pci_generic 驱动程序。

软件轮询模式驱动程序 (PMD)

除此之外,DPDK 附带的一系列软件 PMD 不需要通用内核 PCI 驱动程序,而是依赖标准内核基础设施来提供硬件支持。这样,DPDK 几乎可以与任何硬件一起使用,即使 DPDK 本身不支持。

PCAP 库是广泛使用且受支持的数据包捕获库,适用于网络 硬件。目前,DPDK 已为 PCAP 库提供了 PMD。 DPDK 还支持使用 AF_PACKET PMD 的 Linux 网络,并且 DPDK 也原生支持 AF_XDP。虽然使用这些 PMD 会产生性能成本(有时相当大),但优点是设置很容易,而且这些 PMD 通常根本不关心 IOVA 模式。

总结

本文深入介绍了 DPDK 如何处理物理内存,并概述了 DPDK 在使用各种 Linux* 内核驱动程序时提供的物理寻址功能。

-->
登录后参与评论