运行程序

环境检测

  • kernel version >= 2.6.34

  • glibc >= 2.7

  • 内核配置

    • uio支持:zcat /proc/config.gz | grep -i uio

    • hugetlbfs支持:zcat /proc/config.gz | grep -i huge

    • PROC_PAGES_MONITOR支持:zcat /proc/config.gz | grep -i proc_page

    • HPET支持(按情况可选):zcat /proc/config.gz | grep -i hpet

配置

开启Huge Pages

可以在系统启动时候或启动后开启

启动前分配

sudo vim /etc/default/grub

# 编辑 GRUB_CMDLINE_LINUX_DEFAULT 或 GRUB_CMDLINE_LINUX
# 添加
# default_hugepagesz=1G hugepagesz=1G hugepages=4

启动后分配(特例)

对于2MB页面,还可以在系统启动之后再分配,通过向 /sys/devices/ 目录下的nr_hugepages文件写入hugepage数目来实现。 对于单节点系统,使用的命令如下(假设需要1024个页):

echo 1024 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages

在NUMA设备中,分配应该明确指定在哪个节点上:

echo 1024 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
echo 1024 > /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages

使用HugePages

一旦预留了hugepage内存,为了使内存可用于DPDK,请执行以下步骤:

mkdir /mnt/huge
mount -t hugetlbfs nodev /mnt/huge

或者写在 /etc/fstab 中

nodev /mnt/huge hugetlbfs defaults 0 0

# 对于1G内存,页面大小必须在安装选项中指定
# nodev /mnt/huge_1GB hugetlbfs pagesize=1GB 0 0

加载 UIO 模块

modprobe uio_pci_generic

或使用DPDK提供的UIO

modprobe uio
insmod kmod/igb_uio.ko

uio是一种用户空间I/O模块,它允许用户空间程序与设备驱动程序进行通信。该模块提供一种方法,使用户空间程序可以通过内存映射I/O(MMIO)和中断处理与硬件设备进行交互,而无须编写内核模块。

用户空间程序可以通过将UIO驱动程序加载到内核中,并使用标准的文件I/O接口(如:read()和write())来读取和写入设备寄存器,或者使用mmap()函数来进行内存映射,以实现对设备的访问

UIO模块的工作原理是将设备的物理地址空间映射到用户空间的虚拟地址空间,从而可以直接读写设备寄存器。此外,UIO模块还提供了中断处理功能,使用户空间程序能够接收和处理设备的中断事件。

使用UIO模块,用户程序可以更加灵活的控制和管理硬件设备,而无需深入了解和修改内核代码。这为开发驱动程序和应用程序提供了更高的灵活性和可移植性。

加载 VFIO 模块

modprobe vfio-pci

VFIO是一种虚拟化I/O(VFIO)模块,它提供了一种机制,允许用户空间程序直接访问和控制物理设备,而不需要经过内核。

VFIO模块的主要目的是为虚拟化环境提供高性能的直通设备访问。它允许将物理设备直接分配给虚拟机,从而使虚拟机能够完全访问和控制设备,同时绕过了内核中间层。

通过 VFIO 模块,用户空间程序可以使用 IOMMU(Input/Output Memory Management Unit)来实现设备的安全分离和直通。IOMMU是一种硬件机制,用于将设备的物理地址空间映射到虚拟机的虚拟地址空间。用户空间程序可以使用VFIO接口来管理和控制IOMMU,以及分配和释放设备资源。

VFIO 还提供一些其它功能,例如中断处理和设备重置。它允许用户空间程序注册中断处理程序,以接收和处理设备中的中断事件。此外,VFIO模块还提供了设备重置功能,可以重置设备的状态以确保设备在重新分配给其它虚拟机或用户之前处于干净的状态。

总的来说,VFIO模块提供了一种高性能的机制,使用户空间程序能够直接访问和控制物理设备,为虚拟化环境提供了更好的性能和灵活性。它在需要将设备直通给虚拟机或者需要更高级别的设备访问控制的场景下非常有用。

VFIO和UIO区别

VFIO:主要用于虚拟化环境,特别是在需要将物理设备直通给虚拟机的情况下。它提供了高性能和低延迟的设备访问方式,使虚拟机能够获得与宿主机相同的设备访问能力。

UIO:UIO主要用于用户空间应用程序与设备之间的交互。它提供了一种简化的方式来访问各种类型的硬件设备,如:FPGA、定时器、传感器等。UIO使得用户空间程序能够更加灵活的控制和管理硬件设备,而无需编写内核模块

端口绑定

运行 DPDK 之前需要先解除所有网络端口与原先内核模块的绑定关系,将所有使用的端口绑定到 uio_pci_generic(或者自带的igb_uio) 或 vfio-pci模块上。

绑定与解绑的过程可以使用脚本 dpdk-devbind.py

# 绑定设备 eth1 '04:00.1' 到 uio_pci_generic 驱动

dpdk-devbind.py --bind=uio_pci_generic 04:00.1

或者:
dpdk-devbind.py --bind=uio_pci_generic eth1

恢复设备 02:00.0 到Linux内核绑定状态:

dpdk-devbind.py --bind=ixgbe 82:00.0