返回

DPDK非root权限运行:解决Permission denied问题

Linux

DPDK 应用非 root 权限运行:问题排查与解决

碰到了 DPDK helloworld 应用以非特权用户身份运行时报错的问题?别急,咱们一起来看看怎么解决。

报错信息大概长这样:

[@dredd examples]$ ./dpdk-helloworld
EAL: Detected CPU lcores: 4
EAL: Detected NUMA nodes: 1
EAL: Detected static linkage of DPDK
EAL: Multi-process socket /run/user/1000/dpdk/rte/mp_socket
EAL: rte_mem_virt2phy(): cannot open /proc/self/pagemap: Permission denied
EAL: FATAL: Cannot use IOVA as 'PA' since physical addresses are not available
EAL: Cannot use IOVA as 'PA' since physical addresses are not available
PANIC in main():
Cannot init EAL
5: [./dpdk-helloworld(_start+0x2e) [0x58ce4e]]
4: [/lib64/libc.so.6(__libc_start_main+0xf3) [0x7f93977edcf3]]
3: [./dpdk-helloworld(main+0x42) [0x58cf87]]
2: [./dpdk-helloworld(__rte_panic+0xdb) [0xa01c59]]
1: [./dpdk-helloworld(rte_dump_stack+0x27) [0xa2fcac]]

明显是权限问题,/proc/self/pagemap 文件访问被拒绝了。

问题根源:/proc/self/pagemap 与权限

DPDK 需要通过 /proc/self/pagemap 获取虚拟地址到物理地址的映射,这是实现高性能数据包处理的关键。 但从 Linux 内核 4.0 开始,普通用户默认无法直接访问其他进程的 /proc/<pid>/pagemap

虽然官方文档建议给可执行文件添加 cap_ipc_lockcap_sys_admin capabilities,但这可能还不够。 因为问题核心在于访问/proc/self/pagemap, 仅仅有capabilities可能不足以更改Linux内核的安全策略.

解决方法

咱们一步步来排查、解决。

1. 确认 Capabilities

先确认下 capabilities 是否正确设置:

sudo setcap cap_ipc_lock,cap_sys_admin+ep ./dpdk-helloworld
getcap ./dpdk-helloworld

如果输出类似 ./dpdk-helloworld = cap_ipc_lock,cap_sys_admin+ep,说明设置成功。 如果这里就有问题, 那需要检查一下setcap 命令是否执行成功,可能需要 sudo 权限。

2. 调整 /proc/sys/vm/unprivileged_userfaultfd (如果适用)

某些情况下,即使设置了 capabilities,仍可能遇到权限问题。可以尝试调整内核参数:

sudo sysctl -w vm.unprivileged_userfaultfd=1

这条命令允许非特权进程使用 userfaultfd 系统调用。但请注意,这可能会降低系统的安全性, 在生产环境不建议开启.

3. 修改内核参数 pagemap_read (推荐)

从根本上解决, 更改/proc/sys/kernel/pagemap_read:

临时修改(重启后失效):

echo 1 | sudo tee /proc/sys/kernel/pagemap_read # 允许所有用户
#或者
echo 2 | sudo tee /proc/sys/kernel/pagemap_read # 属于有CAP_SYS_ADMIN capability 的用户

永久修改:

编辑 /etc/sysctl.conf 文件,添加一行:

kernel.pagemap_read = 1 #或者2, 看具体需求

然后执行:

sudo sysctl -p

使配置生效。

这个选项控制对 /proc/pid/pagemap 的访问.

  • 0: 默认, 表示只有有CAP_SYS_ADMIN capability的进程才能访问。
  • 1: 任何用户进程可以访问.
  • 2: 属于有CAP_SYS_ADMIN capability 的用户或进程可以访问。

这个是安全性和功能之间的平衡点. 通常选择 2 会好一些。

4. Hugepages 配置

DPDK 大量使用 hugepages 提升性能。确认 hugepages 已经正确配置:

  • 查看当前 hugepages 配置:

    cat /proc/meminfo | grep Huge
    
  • 分配 hugepages(例如,分配 1024 个 2MB 大小的 hugepages):

    echo 1024 | sudo tee /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
    
  • 挂载 hugepages 文件系统:

    sudo mkdir /mnt/huge
    sudo mount -t hugetlbfs nodev /mnt/huge
    
  • 考虑持久化 hugepages 配置。编辑 /etc/fstab,添加类似如下一行:

    nodev /mnt/huge hugetlbfs defaults 0 0
    

5. 调整用户限制 (ulimit)

检查并调整当前用户的 memlock 限制, 它控制了进程可以锁定的内存量。

  • 查看当前限制:

    ulimit -l
    
  • 临时调整(当前 shell 会话有效):

    ulimit -l unlimited
    
  • 永久调整(编辑 /etc/security/limits.conf 文件,添加类似如下行):

    your_username - memlock unlimited
    

    (将 your_username 替换为你的用户名)。

    重新登录或使用 su - your_username 使配置生效。

6. 考虑使用 VFIO (进阶)

如果你的应用需要直接操作硬件设备,并且你已经将设备绑定到 VFIO 驱动,确保正确配置了 VFIO:

  • 确认设备已经绑定到 VFIO 驱动(lspci -k 可以查看)。
  • 查看一下 iommu group, 同一个 group 的设备,在权限上被视为一体。 使用非 root 用户时,要保证你的目标设备有自己单独的 IOMMU group, 或者,就要更仔细地调整 IOMMU相关的权限控制.
  • 检查/dev/vfio 目录和设备的权限,确保你的用户有读写权限。有时需要用 chownchmod 修改权限。

如果上述步骤都检查过了还是有问题, 请先从内核安全日志(dmesg)看看有没有具体的拦截记录, 更具体地定位出错原因.
不同的系统设置, 出错情况和最终需要的改动也会有一些差别, 请务必小心操作和测试.