3. 内核配置:编译内核时开启 VFIO 相关选项

要使 DPDK 能够通过 VFIO 驱动将网卡直通给用户态程序,Linux 内核必须在编译时开启 IOMMU、VFIO 以及 VFIO-PCI 三个核心功能模块。本章节将详细说明内核配置的步骤、关键选项的位置以及配置后的验证方法。

前置条件:确保你已获取内核源码并完成基础的环境准备(如安装必要的编译工具链、ncurses 库等)。推荐使用与当前系统版本匹配或稍新的长期支持(LTS)内核版本。

3.1 核心配置选项概览

VFIO 直通依赖的三大内核子系统及其在 make menuconfig 中的路径如下表所示:

子系统 配置路径(make menuconfig) 关键选项名称 推荐设置
IOMMU Device Drivers → IOMMU Hardware Support IOMMU_SUPPORT、INTEL_IOMMU 或 AMD_IOMMU 编译进内核(*)
VFIO 核心 Device Drivers → VFIO Non-Privileged userspace driver framework VFIO、VFIO_IOMMU_TYPE1 编译进内核(*)或模块(M)
VFIO-PCI Device Drivers → VFIO Non-Privileged userspace driver framework → VFIO support for PCI devices VFIO_PCI 编译为模块(M)
关键说明:IOMMU 通常建议编译进内核(*),以确保系统启动时即启用;VFIO 核心和 VFIO-PCI 可以编译为模块(M),便于按需加载和卸载。

3.2 逐步配置流程

以下步骤基于 make menuconfig 图形化配置界面,适用于大多数 Linux 发行版:

  1. 进入内核源码目录并启动配置界面:
    cd /usr/src/linux
    make menuconfig
  2. 开启 IOMMU 支持:
    • 进入 Device Drivers → IOMMU Hardware Support。
    • 选中 IOMMU Support(按 Y 键)。
    • 根据 CPU 平台选择对应的 IOMMU 驱动:
      • Intel 平台:选中 Support for Intel IOMMU using DMA Remapping Devices (DMAR)。
      • AMD 平台:选中 AMD IOMMU Support。
    • 建议同时开启 Support for Interrupt Remapping(如果平台支持),以支持 MSI/MSI-X 中断重映射。
  3. 开启 VFIO 框架:
    • 返回主菜单,进入 Device Drivers → VFIO Non-Privileged userspace driver framework。
    • 选中 VFIO Non-Privileged userspace driver framework。
    • 进入子菜单,选中 VFIO IOMMU Type1 support(提供 Type1 IOMMU 后端,DPDK 依赖此模块)。
  4. 开启 VFIO-PCI 驱动:
    • 在 VFIO 子菜单中,找到 VFIO support for PCI devices 并选中。
    • 建议按 M 键编译为模块,以便在需要时通过 modprobe vfio-pci 加载。
  5. 保存并退出:
    • 按 Save 保存配置到 .config 文件。
    • 按 Exit 退出配置界面。
常见遗漏:许多开发者只开启了 VFIO 和 VFIO-PCI,却忽略了 IOMMU 子系统的配置,导致后续绑定网卡时出现 No IOMMU support 错误。请务必确认 IOMMU 相关选项已正确开启。

3.3 内核配置选项关系图

下图展示了 IOMMU、VFIO 核心与 VFIO-PCI 之间的依赖关系及数据流路径:

内核 VFIO 直通配置依赖关系 IOMMU 子系统 INTEL_IOMMU / AMD_IOMMU VFIO 核心框架 VFIO + VFIO_IOMMU_TYPE1 VFIO-PCI 驱动 VFIO_PCI (模块) 提供 DMA 重映射 注册 PCI 驱动 DPDK 用户态应用 通过 VFIO 访问网卡 设备文件 /dev/vfio/ 配置要点: 1. IOMMU 必须编译进内核(*),VFIO 核心和 VFIO-PCI 可编译为模块(M)。 2. 开启 Interrupt Remapping 支持以启用 MSI/MSI-X 中断直通。

3.4 编译与安装新内核

配置完成后,执行以下命令编译并安装内核:

# 编译内核和模块(使用 -jN 加速,N 为 CPU 核心数)
make -j$(nproc)

# 安装模块
sudo make modules_install

# 安装内核
sudo make install

# 更新引导配置(以 GRUB 为例)
sudo update-grub
编译加速:如果仅修改了 VFIO 相关选项,可以使用 make localmodconfig 生成精简配置,或使用 make -j$(nproc) drivers/vfio/ 仅编译 VFIO 子系统模块以节省时间。

3.5 验证内核配置是否生效

重启系统并选择新内核启动后,通过以下方法验证配置是否生效:

  • 检查内核配置:
    cat /boot/config-$(uname -r) | grep -E "CONFIG_VFIO|CONFIG_IOMMU"
    预期输出应包含:
    CONFIG_IOMMU_SUPPORT=y
    CONFIG_INTEL_IOMMU=y
    CONFIG_VFIO=y
    CONFIG_VFIO_IOMMU_TYPE1=y
    CONFIG_VFIO_PCI=m
  • 检查 VFIO 模块是否加载:
    lsmod | grep vfio
    如果 VFIO-PCI 编译为模块,需要手动加载:
    sudo modprobe vfio-pci
  • 检查 IOMMU 是否启用:
    dmesg | grep -i iommu
    应看到类似 Intel-IOMMU: enabled 或 AMD-Vi: enabled 的信息。
内核启动参数:即使内核开启了 IOMMU,某些平台还需要在 GRUB 内核命令行中添加 intel_iommu=on(Intel)或 amd_iommu=on(AMD)才能强制启用。编辑 /etc/default/grub 中的 GRUB_CMDLINE_LINUX 并运行 update-grub。

3.6 常见配置错误与排查

错误现象 可能原因 解决方案
DPDK 报错 EAL: No IOMMU support 内核未开启 IOMMU 或启动参数缺失 检查 CONFIG_IOMMU_SUPPORT 和 CONFIG_INTEL_IOMMU;添加 intel_iommu=on 启动参数
modprobe vfio-pci 失败 VFIO_PCI 未编译或未安装 确认 CONFIG_VFIO_PCI=m;重新编译并安装模块
网卡绑定 VFIO 后无法识别 VFIO 核心模块未加载 执行 modprobe vfio 和 modprobe vfio_iommu_type1
中断配置失败 未开启 Interrupt Remapping 开启 CONFIG_IRQ_REMAP 并重新编译内核
最佳实践:建议在编译内核前,使用 make olddefconfig 基于当前系统配置生成默认值,再手动调整 VFIO 相关选项,避免遗漏其他依赖项。