使用Valgrind运行DPDK示例程序dpdk-testpmd时启动卡住求助
问题现象
使用Valgrind运行DPDK示例程序(如dpdk-testpmd)时,程序在启动阶段卡住,相关日志如下:
[root@node1 app]# valgrind --leak-check=yes ./dpdk-testpmd -a 0000:af:00.3 ==322313== Memcheck, a memory error detector ==322313== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al. ==322313== Using Valgrind-3.21.0.GIT and LibVEX; rerun with -h for copyright info ==322313== Command: ./dpdk-testpmd -a 0000:af:00.3 ==322313== EAL: Detected CPU lcores: 96 EAL: Detected NUMA nodes: 2 EAL: Detected static linkage of DPDK EAL: Multi-process socket /var/run/dpdk/rte/mp_socket EAL: Selected IOVA mode 'VA' EAL: No available 2048 kB hugepages reported EAL: VFIO support initialized ==322313== Warning: set address range perms: large range [0x140000000, 0x980000000) (noaccess) ==322313== Warning: set address range perms: large range [0x940000000, 0x980000000) (noaccess) ==322313== Warning: set address range perms: large range [0x100b967000, 0x184b967000) (noaccess) ==322313== Warning: set address range perms: large range [0x100b967000, 0x184b967000) (noaccess) ==322313== Warning: set address range perms: large range [0x100b967000, 0x184b967000) (noaccess) ==322313== Warning: set address range perms: large range [0x100b967000, 0x184b967000) (noaccess) ==322313== Warning: set address range perms: large range [0x100b967000, 0x184b967000) (noaccess) ==322313== Warning: set address range perms: large range [0x100b967000, 0x184b967000) (noaccess) ==322313== Warning: set address range perms: large range [0x100b967000, 0x184b967000) (noaccess) ==322313== Warning: set address range perms: large range [0x100b967000, 0x184b967000) (noaccess) ==322313== Warning: set address range perms: large range [0x100b967000, 0x184b967000) (noaccess) ==322313== Warning: set address range perms: large range [0x100b967000, 0x184b967000) (noaccess) ==322313== Warning: set address range perms: large range [0x100b967000, 0x184b967000) (noaccess) EAL: WARNING! Base virtual address hint (0xa80001000 != 0x1040000000) not respected! EAL: This may cause issues with mapping into secondary processes ==322313== Warning: set address range perms: large range [0x100b967000, 0x1040000000) (noaccess)
而直接运行程序时完全正常:
[root@node1 app]# ./dpdk-testpmd -a 0000:af:00.3 EAL: Detected CPU lcores: 96 EAL: Detected NUMA nodes: 2 EAL: Detected static linkage of DPDK EAL: Multi-process socket /var/run/dpdk/rte/mp_socket EAL: Selected IOVA mode 'VA' EAL: No available 2048 kB hugepages reported EAL: VFIO support initialized EAL: Using IOMMU type 1 (Type 1) EAL: Probe PCI driver: net_ice (8086:1593) device: 0000:af:00.3 (socket 1) ice_load_pkg_type(): Active package is: 1.3.28.0, ICE OS Default Package (double VLAN mode) TELEMETRY: No legacy callbacks, legacy socket not created testpmd: create a new mbuf pool <mb_pool_0>: n=203456, size=2176, socket=0 testpmd: preferred mempool ops selected: ring_mp_mc testpmd: create a new mbuf pool <mb_pool_1>: n=203456, size=2176, socket=1 testpmd: preferred mempool ops selected: ring_mp_mc Warning! port-topology=paired and odd forward ports number, the last port will pair with itself. Configuring Port 0 (socket 1) ice_set_rx_function(): Using AVX2 Vector Rx (port 0). Port 0: B4:96:91:A7:66:57 Checking link statuses... Done No commandline core given, start packet forwarding io packet forwarding - ports=1 - cores=1 - streams=1 - NUMA support enabled, MP allocation mode: native Logical Core 1 (socket 0) forwards packets on 1 streams: RX P=0/Q=0 (socket 1) -> TX P=0/Q=0 (socket 1) peer=02:00:00:00:00:00 io packet forwarding packets/burst=32 nb forwarding cores=1 - nb forwarding ports=1 port 0: RX queue number: 1 Tx queue number: 1 Rx offloads=0x0 Tx offloads=0x10000 RX queue: 0 RX desc=1024 - RX free threshold=32 RX threshold registers: pthresh=0 hthresh=0 wthresh=0 RX Offloads=0x0 TX queue: 0 TX desc=1024 - TX free threshold=32 TX threshold registers: pthresh=32 hthresh=0 wthresh=0 TX offloads=0x10000 - TX RS bit threshold=32 Press enter to exit
需求为调试链接DPDK库的应用中常规malloc调用分配的内存区域的泄漏或损坏问题,而非DPDK自身rte_*系列内存接口的问题。
原因分析
Valgrind默认会拦截并跟踪所有内存操作,但DPDK依赖大页内存、自定义内存管理框架,这些内存区域的地址空间范围大、权限设置特殊,会被Valgrind反复拦截处理,导致性能急剧下降甚至卡住。同时DPDK的内存布局逻辑与Valgrind的地址空间管理存在冲突,触发大量地址权限警告,最终卡在内存初始化阶段。
解决方案
1. 排除DPDK内存区域的Valgrind检测
从Valgrind日志中提取所有警告的内存范围,用--exclude-range参数跳过这些区域的检测,让Valgrind只关注常规malloc的内存:
valgrind --leak-check=yes \ --exclude-range=0x140000000-0x980000000 \ --exclude-range=0x100b967000-0x184b967000 \ --exclude-range=0x100b967000-0x1040000000 \ ./dpdk-testpmd -a 0000:af:00.3
如果范围较多,可将所有范围写入文件(每行一个范围,格式为0x起始地址-0x结束地址),用--exclude-range-file参数加载:
# 先创建exclude_ranges.txt文件,写入所有需要排除的内存范围 valgrind --leak-check=yes --exclude-range-file=exclude_ranges.txt ./dpdk-testpmd -a 0000:af:00.3
2. 降低Valgrind的拦截开销
添加以下参数减少Valgrind对DPDK内存操作的拦截和优化,提升运行效率:
--vex-iropt-level=0:降低VEX中间代码的优化级别,减少对DPDK特殊内存操作的处理--trace-children=no:禁止跟踪DPDK创建的子进程(如果有)
示例命令:
valgrind --leak-check=yes --vex-iropt-level=0 --trace-children=no \ --exclude-range=0x140000000-0x980000000 \ ./dpdk-testpmd -a 0000:af:00.3
3. 优化DPDK启动参数
限制DPDK的内存使用量,减少Valgrind需要处理的内存范围:
--socket-mem=1024,1024:指定每个NUMA节点使用1GB内存(根据实际需求调整)--no-telemetry:关闭DPDK遥测功能,减少不必要的内存操作--disable-hugepages:如果应用允许,禁用大页(部分DPDK功能依赖大页,需谨慎使用)
示例命令:
valgrind --leak-check=yes --exclude-range=0x140000000-0x980000000 \ ./dpdk-testpmd -a 0000:af:00.3 --socket-mem=1024,1024 --no-telemetry
4. 编译DPDK时启用Valgrind兼容选项
如果可以重新编译DPDK,添加CONFIG_RTE_VALGRIND=y配置,让DPDK在Valgrind环境下自动调整内存操作逻辑,避免冲突:
# 进入DPDK源码目录 meson setup build -Dvalgrind=true ninja -C build
使用编译后的DPDK库链接应用后,再用Valgrind运行即可。
验证
按照上述方法运行后,DPDK程序可正常启动,Valgrind仅检测常规malloc/free分配的内存区域,不会再卡在启动阶段,满足调试需求。
内容的提问来源于stack exchange,提问作者ssrini78

