news 2026/9/29 15:45:33

DPDK Testpmd实战:最小命令、性能压测与避坑指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DPDK Testpmd实战:最小命令、性能压测与避坑指南

简介:一份面向互联网与网络数据面开发者的应用指南,围绕 DPDK 自带 testpmd 示例程序展开;testpmd 既能用于包转发模式下的性能测试,也能访问 Flow Director 等 NIC 硬件特性,同时也是基于 DPDK SDK 构建更完整应用时的参考样板。压缩包内为单份 PDF 文档,大小仅 137KB,已有 599 人学习。文档先从编译流程讲起,说明如何用 make、gcc 等工具并配合 -m64 等选项指定目标平台与架构;随后介绍 EAL 与 testpmd 的命令行选项,帮助读者指定 NIC 接口、包转发模式和 Flow Director 等运行参数,并理解 DPDK 在数据包处理中的基本机制。运行时函数部分按功能模块梳理了帮助、控制、显示、配置、端口、链路绑定、寄存器与过滤器等常用操作,基本覆盖日常性能测试、NIC 特性验证与调试场景;内容预览还显示,文档包含 Introduction、Overview、Compiling、Running、Runtime Functions 等章节,结构清晰,便于按需查阅。对希望掌握 DPDK 包转发流程、NIC 配置方法并快速上手 testpmd 的读者来说,这份指南提供了从编译到运行的完整路径,能帮助理解 EAL、Packet Framework 与 NIC Poll Mode Driver 的协作方式,适合入门与进阶参考。

1. DPDK Testpmd 应用:先弄清它在真实开发里解决什么问题

在 DPDK 的中文技术社区里,Testpmd 可能是命令行被复制最多、解释最少的一个应用。捧着《DPDK Testpmd 应用》这类 PDF 从头翻到尾,你会发现它更像一本参数字典:一大堆命令行选项、转发模式、端口操作命令,却没有告诉你第一步该敲哪条命令。它的真实角色其实是网卡驱动和转发路径的“试金石”:验证 PMD 驱动能不能稳定收包,压一压单核能跑多少 Mpps,看看多队列 RSS 是否把流量均匀分发。适合做 DPDK 驱动开发、NFV 转发面、OVS-DPDK 调优的人,也适合刚把环境编译好、想确认硬件没有白买的初学者。接下来这篇实战笔记会从跑通最小命令一路讲到性能压测和踩坑,把 Testpmd 最有用的那部分落到键盘上。

2. 用最小命令跑通 Testpmd:先让它把包转起来

2.1 一条能转发报文的启动命令

第一次接触 Testpmd 的人,最好先忘掉“背参数”这件事,直接把下面这条命令粘到终端里。前提是你已经把网卡用dpdk-devbind.py绑到vfio-pci或igb_uio驱动,并且分配了足够的大页内存。

dpdk-testpmd -l 0-1 --huge-dir /dev/hugepages -n 2 \ -a 0000:01:00.0 \ -- -i --portmask=0x1 --rxd=1024 --txd=1024 --burst=64

这条命令的意图是:用 CPU 0 和 CPU 1 两个逻辑核跑 Testpmd,从/dev/hugepages目录取大页内存,假定主板有 2 个内存通道,并只操作 PCI 地址为0000:01:00.0的那块网卡。--后面是 Testpmd 自己的参数,-i表示进入交互模式,这样你在启动后不会直接转发,而是先停在控制台前,输入start才真正开始收发包。

参数这里拆开说一下。-l 0-1建议你选两个不超频、不被打扰的核,必要时用-l指定核而不是让 DPDK 自己乱挑。-n 2是内存通道数,一般可以从 BIOS 或dmidecode查,填错了顶多性能差点,不会报错。--rxd和--txd是收发描述符环的大小,默认很多时候只有 256,对 10G 网卡来说容易丢包,设成 1024 或 2048 更稳。--burst=64是每次从网卡取包的最大数量,这个值决定了收包引擎分批次处理的粒度,64 是一个对延迟和吞吐都相对平衡的默认值。

2.2 端口、核和内存池的选型逻辑

Testpmd 启动时会创建若干个内存池,默认情况下一个收一个发。内存池的 block size 来自启动参数--mbuf-size,默认是 2048 字节,刚好覆盖一个标准 MTU 报文加头部和分片需要的空间。如果你们的报文带 VXLAN 或者更大的 metadata,建议改大,否则收包阶段就会因为 mbuf 不够放而丢包。

关于核的用法,-l指定的是 DPDK EAL 可以使用的逻辑核,不是让你一个核给收、一个核给发。Testpmd 的线程模型是“一个转发核同时跑收和发”,所以你通常会看到--nb-cores这个参数,而不是让用户手动把一对端口塞给某个线程。最常见做法是:

dpdk-testpmd -l 0-15 --huge-dir /dev/hugepages -n 4 \ -a 0000:01:00.0 -a 0000:01:00.1 \ -- -i --nb-cores=8 --rxq=8 --txq=8

--nb-cores=8决定 Testpmd 启用多少个转发线程,每个线程挂在不同的核上。--rxq和--txq是端口队列数,队列数和转发线程数不强制一致,由 Testpmd 自动分配。这里我们分配 8 个线程、8 个队列,如果 RSS 配置正确,每个核各占一个队列,不会出现多个核抢同一个队列的锁竞争。

内存池数量也值得注意。Testpmd 内部经常出现allocation of mbuf pool失败的报错,原因往往是--mbuf-size改得太大,导致 sum of all requests 超过大页内存。我一般会保持默认--mbuf-cache=32,只在报文变大时调整--mbuf-size,而不是去动 cache。cache 太小会让每个核频繁回写全局 list,影响吞吐,太大又会多占内存。

2.3 为什么默认是 io forwarding,mac forwarding 又差在哪

默认转发模式是iofwd,它只做一件事:从某端口收,原封不动从另一个端口或同一个端口发出去,不改 MAC、不改 IP。这种模式非常适合测收发包引擎纯净吞吐。另一常见模式是macfwd,它会改写目的 MAC 再转发,模拟真实二层交换机的转发路径。两者在 Testpmd 命令行里几乎没有性能差,但macfwd要对每个报文做一次头部修改,开销略高一点点,做性能对标时必须写清楚用的是哪个模式。

如果你想模拟跨网段或者三层转发,还可以用flow模板,但生产环境里大家一般不会让 Testpmd 做复杂流表匹配测试,那些都交给硬件卸载或更高层的转发应用。Testpmd 的价值在于把底层报文的走向看得清清楚楚:

set fwd mac start show port stats all

上面这组命令把转发模式切成 mac 转发并启动,接着打印所有端口的收发统计。统计里有rx-packets、tx-packets、rx-dropped和tx-dropped。测试互连时对端如果没收到包,先看rx-packets是在涨还是停在 0,这是最简单的一层定位。注意,set fwd mac只改转发引擎类型,不需要重启端口。

2.4 打通环回的三种做法

支持 loopback 的网卡,可以加--port-topology=loopback让单个端口自发自收,适合没有双端口设备的调试场景。命令如下:

dpdk-testpmd -l 0-1 -a 0000:01:00.0 \ -- -i --port-topology=loopback --forward-mode=io

链路如果没起来,先执行set link up port 0,再看show port info 0里的link status。另一种场景是端口不支持硬件 loopback,那就必须用一根双口网卡把两个端口用光纤或网线环起来,--port-topology=chained对这种情况尤其好用,它允许一个转发核连续处理多个端口。区别在于 chained 拓扑下每个核依次服务所有端口,而 paired 是固定成对转发,吞吐性能差异在高端多口网卡上能看出来。

3. 用 Testpmd 做性能压测:吞吐、时延与丢包的正确读法

3.1 吞吐测试的典型步骤:外部打流加 iofwd

Testpmd 本身不是一个完整流量发生器,所以测吞吐最可靠的做法是:被测设备装 Testpmd,测试仪从外部向端口打流,Testpmd 转发,测试仪读回数据。这样得到的是整条路径有没有丢包。启动参数建议按前面推荐来:--rxd=2048 --txd=2048 --burst=64 --nb-cores=2 --rxq=2 --txq=2。

dpdk-testpmd -l 4-5 --huge-dir /dev/hugepages -n 2 \ -a 0000:af:00.0 -a 0000:af:00.1 \ -- -i --rxd=2048 --txd=2048 --burst=64 \ --rxq=2 --txq=2 --forward-mode=io

进入交互界面后,按照测试计划先把端口状态拉起来,再启动转发:

port stop all set link up port 0 set link up port 1 start show port stats all

外部打流的速率建议从线速的 50% 开始,逐步加到一个包长下刚好不丢的速率,再用 Testpmd 的set burst 128之类调整 batch 大小,看是否影响转发吞吐。官方文档里经常出现 Mpps 这个单位,我更习惯直接看 Testpmd 输出的rx-packets与tx-packets,两者之差就是被转丢的包数。丢包率不能拿测试仪一个端口的发包数去对,最好以 Testpmd 收到的包数为基准,这样能把入口丢包也算进去。

3.2 txonly 和 rxonly:用一块网卡也能做单方向压力

没有测试仪时,可以用 Testpmd 的txonly模式生成高速无意义 UDP 包,直接把数据从端口发出去。配合对端用rxonly或者另一台机器的 Testpmd 收包,就能测出单纯的发送能力。用法很简单:

set fwd txonly set txpkts 64 start

set txpkts 64把生成的报文大小固定成 64 字节,这是以太网最小帧长,能把转发资源推到极限。测试完成后stop,再用show port stats all看tx-packets。注意txonly模式下rx-packets通常仍是 0,它不会处理入向流量,所以不要拿 rx 统计去判断发送吞吐。

反过来rxonly只负责从网卡收包并直接丢进 mbuf 池,不转发。它可以和外部打流设备配合,测出网卡驱动在纯接收模式下能收到多少包,同时不会因为转发环上的 CPU 瓶颈掩盖接收瓶颈。两次测试一个收一个发,也能定位性能瓶颈是出在收方向还是发方向。

3.3 多队列和 RSS:压测配置要和生产一致

在正式性能验证里,只开单队列跑 Testpmd 没有参考意义,因为生产环境的 OVS-DPDK 或 VPP 都是多队列加 RSS。Testpmd 支持运行时配置 RSS,我一般会这么操作:

port config rss all ipv4 show port rss all set fwd io start

用port config rss all ipv4对所有端口开启 IPv4 哈希。测试前务必用show port rss all确认哈希类型真的写进去了,否则流量可能因为哈希函数默认只看外层 MAC 而全部押到一个队列。很多人压测时遇到“流量全部在核 0 上空转,其他核看着”,十有八九是 RSS 没开,或者哈希字段选错了。

观察各队列计数可以用show port xstats all,里面能看到rx_q0_packets、rx_q1_packets这样的登记项,确认是否均匀。不均匀的原因很多:测试流的五元组不够随机、哈希种子偏了、多队列下队列数量不是 2 的幂导致取模不均匀。这些都是踩过坑之后才会下意识去检查的项。

3.4 结果记录:参数要完整,结论才有可比性

Testpmd 的压测结果很难复现,最常翻车的原因是记录参数太随意。一个可交付报告里至少要包含:网卡型号和固件版本、驱动名称和 DPDK 版本、绑定模式(vfio-pci/igb_uio)、大页配置、CPU 型号和核绑定、内存通道数、端口数和拓扑、rxd/txd、burst、队列数、转发模式、报文长度、打流速率、持续时间、观察到的丢包率。用表格式记录会直观很多:

项目测试配置
DPDK 版本22.11
网卡Intel E810 / Mellanox ConnectX-6
驱动绑定vfio-pci
核 / 队列8 核 / 8 队列
rxq / txq 描述符2048 / 2048
转发模式iofwd
报文长度64B / 1500B
吞吐14.1 Mpps(64B)

原始日志要保留,不只看截图。Testpmd 退出时通常会在 stdout 打印一段简短的统计,用重定向存成文件,后续才能定位是哪个参数变了导致性能下降。

4. Testpmd 控制台交互:跑测试时这些命令能省一半时间

4.1 最有价值的 show 命令

Testpmd 的控制台比很多人想象的强得多。你不需要每改一个参数就重启进程,大量动作都在运行中完成。先记住这组show:

show port info all show port stats all show port xstats all show port rss all

show port info all看硬件状态和链路;show port stats all看累计收发和丢包;show port xstats all看每个队列单独的计数,是排查 RSS 是否均匀的关键;show port rss all看哈希配置。如果你在跑长时间稳定性测试,想确认进程没有卡死,连续执行两次show port stats all,计数在增长就说明数据路径还活着。

4.2 运行中调参的命令

转发过程中可以调整的参数分成三类:端口状态、转发引擎参数、队列配置。端口状态用port stop all/port start all控制,链路状态用set link up/down port N。转发引擎参数像set fwd切模式,set burst N调 batch,set txpkts改发包长度。队列配置比较麻烦,Testpmd 不允许运行中直接改已经启用的 rxq/txq 数量,常见做法是先停掉端口,再改队列数,最后重新启动:

port stop all port config rxq all 8 port config txq all 8 port config rss all ipv4 port start all start

这段操作的意义是验证多队列切换后 RSS 仍然生效。注意port config rxq之后队列数变了,但转发核数量没有变,Testpmd 会自动重新分配队列到核,最好用show cfg看一眼分配结果,避免某个核背了多条队列而另一个核闲着。

4.3 用-f文件加大外层脚本组合成批处理

如果测试经常重复,手工敲命令就很浪费。Testpmd 支持用-f参数接一个命令文件,文件里每一行就是一条交互命令,启动后会顺序执行。先写一个只做配置和启动的文件tp_start.txt:

port stop all set fwd io set burst 64 port config rss all ipv4 port start all start

再用 FIFO 配合 bash 控制时序:

mkfifo /tmp/tp_cmd dpdk-testpmd -l 0-1 --huge-dir /dev/hugepages -n 2 \ -a 0000:01:00.0 -- -i -f tp_start.txt < /tmp/tp_cmd & TP_PID=$! exec 3>/tmp/tp_cmd sleep 10 echo "show port stats all" >&3 echo "stop" >&3 echo "quit" >&3 wait $TP_PID

-f负责把配置和启动动作固化,sleep 10控制实际转发时间,后续命令通过 FIFO 发给 Testpmd 的 stdin。这种方式比“人盯着终端回车”可靠,尤其适合放回 CI 里做冒烟测试。注意 FIFO 需要在写之前先打开读端,否则进程会卡在 open 上,这就是很多脚本“看起来没反应”的原因。

5. Testpmd 实战避坑:5 个反复出现的疑难问题

5.1 启动报 EAL 内存分配失败

  • 现象:不管怎么调--mbuf-size都出现EAL: No memory available或者hugepages not enough,进程直接退出。
  • 原因:大页内存根本没准备好。多数情况下是/dev/hugepages没有挂载,或者vm.nr_hugepages设置得比网卡需要的还少。
  • 解决:先看/proc/meminfo里的HugePages_Free,如果是 0,用sysctl vm.nr_hugepages=1024并挂载 hugetlbfs。再启动 Testpmd,指定--huge-dir /dev/hugepages。如果还不行,检查双路台机上每个 socket 是否都分配了大页,DPDK 默认优先在本 socket 用页,需要--socket-mem显式指定两个节点的内存大小。

5.2 绑定 vfio-pci 时提示操作不允许

  • 现象:用dpdk-devbind.py绑定网卡到vfio-pci时出现cannot open /dev/vfio/vfio或者operation not permitted。
  • 原因:用户空间进程没有访问 vfio 设备的权限,或者是 IOMMU 被 BIOS 或内核参数关掉了。
  • 解决:确认内核已经加载vfio_pci模块,启动参数里有iommu=pt。把当前用户加入vfio组,或者临时用chmod 666 /dev/vfio/vfio验证权限问题。绑定完后再用dpdk-devbind.py -s看驱动列,确认已经从ixgbe/i40e换成vfio-pci,再启动 Testpmd。

5.3 Testpmd 收到了包,转发出去却是 0

  • 现象:show port stats all里rx-packets一直在涨,tx-packets停在 0,或者两个口数据对调。
  • 原因:用的端口对和实际接线不一致,或者forward-mode=io时端口编号让 Testpmd 认为两个端口不成对,常见于多端口网卡和 NUMA 节点不匹配。
  • 解决:用show port info all确认链路状态,再对照物理网口的 PCIe 接口编号,把命令里的--portmask改成实际要用的前端口。转发前建议先用set fwd mac,让 Testpmd 改写目的 MAC,这样对端如果也在同一个广播域里,能看到报文到底是从哪张卡出来的,方便手工定位。

5.4 多队列下流量全挤到一个核

  • 现象:show port xstats all里rx_q0_packets是大头,其他队列几乎为零,转发吞吐一直上不去。
  • 原因:RSS 没有打开,或者哈希字段没有覆盖报文的五元组。还有一种可能是启动时没有设置--rxq=8,Testpmd 默认只有 1 个队列,RSS 再开也只有 1 个队列可用。
  • 解决:先看show port rss all,执行port config rss all ipv4并确认哈希字段有值。再把队列数量改成核数:port stop all、port config rxq all 8、port start all。如果还是不平均,检查打流工具是不是只用了同一组源目 IP,五元组不随机,哈希当然均匀不了。

5.5 交互终端被刷屏,命令输不进去

  • 现象:Testpmd 运行中每隔一秒打印一堆计数器,你在控制台敲的命令被刷得几乎看不见。
  • 原因:启动参数里带了--stats-period且设得很小,或者 Testpmd 内部启用了set verbose 2之类的调试输出。
  • 解决:不想看刷屏就去掉--stats-period,或者临时用set verbose 0关掉详细打印。需要周期统计时,把--stats-period设成 60 秒以上,并把日志重定向到文件,交互只保留一个干净的控制台。还有一点:如果用-f脚本,脚本里也别写太频繁的show port stats all,否则一样会有刷屏效果。

6. 把 Testpmd 用得更顺手:脚本化、结果校验和一劳永逸的日志习惯

做网卡驱动或转发面开发,最怕的就是换了一版代码,吞吐数字到底有没有变化说不清楚。我现在会把 Testpmd 装进一个带参数的封装脚本里,一次性跑多种报文长度,并把每次的原始输出留下来。

#!/bin/bash for pkt in 64 256 1024 1500; do log="result_${pkt}.log" cat > tp_cfg.txt <<EOF set fwd txonly set txpkts ${pkt} start EOF timeout 10 dpdk-testpmd -l 0-1 --huge-dir /dev/hugepages -n 2 \ -a 0000:01:00.0 -- -i -f tp_cfg.txt > "$log" 2>&1 grep -E "Tx-packets|Tx-pps|rx-packets" "$log" | tail -3 >> result_summary.txt done

cat生成配置文件,timeout控制每个包长的运行时间,这样每次跑 10 秒后自动退出,统计输出全部落盘,不会因为 Ctrl+C 丢掉最后一段结果。脚本里写的txonly适合验证发送路径,如果要测完整转发,只需要把配置文件里的set fwd txonly换成set fwd io,再把打流器从外部送流量进来即可。

结果校验我习惯用“对账”方式。比如两个端口直接光纤环回,启动 Testpmd 后记录rx-packets和tx-packets,如果两边数字在一个合理的偏差范围内,说明驱动和队列配置没有吞包。真正的交叉验证是端到端:一个端口抓外部流量,另一个端口跑 Testpmd,在外部抓包工具里过滤源 MAC,看是否每条进来的数据都被原样发出。DPDK 进程绕过内核,所以 tcpdump 在 Testpmd 接管网卡上是抓不到包的,千万不要用在内核抓包的结果去推断 Testpmd 丢没丢。

日志习惯是我最想提醒你的一件事。每次跑 Testpmd 前,把命令行、DPDK 版本、网卡固件、大页配置先写进文件名或者日志第一行。不要只存一份结果截图,否则两周后对比数据时,你会连某个参数到底是谁改的都说不清。我吃过这个亏,现在所有测试机上都保留一份testpmd_env.sh,每次跑之前自动把环境信息拼进日志头。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/29 15:45:15

SCSS模块化:从@import到@use与@forward的完整迁移指南

先给结论&#xff1a;如果你还在新项目里用import管理 SCSS 模块&#xff0c;那么你有必要认真看看这篇文章了。Dart Sass 官方已经明确import是弃用功能&#xff0c;并且计划在 Dart Sass 3.0.0 中彻底移除。也就是说&#xff0c;你今天写的import代码&#xff0c;在不久的将来…

作者头像 李华
网站建设 2026/9/29 15:45:14

企业微信外部群API实战:从权限配置到自动化客户运营

先说个结论&#xff1a;企业微信外部群这块 API&#xff0c;恰恰是很多做客户运营的人最容易忽略、但价值极高的一块。我为什么这么说&#xff1f;因为大多数团队在聊企业微信自动化时&#xff0c;眼睛都盯着"客户联系""群发消息""朋友圈"这些明…

作者头像 李华
网站建设 2026/9/29 15:43:55

灌云钢化玻璃加工厂哪家技术强 华昌玻璃加工厂质量参考评选

连云港市华昌玻璃有限公司坐落于连云港海州区洪门工业园&#xff0c;是一家深耕玻璃深加工领域33年的高新技术企业&#xff0c;业务覆盖平钢化、热弯钢化、Low-E中空、夹胶、防火、内置百叶中空、喷砂艺术玻璃等定制加工&#xff0c;可承接办公室弧形隔断、商铺圆弧玻璃、展示柜…

作者头像 李华
网站建设 2026/9/29 15:43:00

2021安徽AI竞赛赛题数据实战:从数据处理到模型提交全流程

简介&#xff1a;面向备战2021年安徽省大数据与人工智能应用竞赛人工智能&#xff08;网络赛&#xff09;本科组的选手及机器学习学习者&#xff0c;这份资料包含当年赛题的两部分核心数据&#xff1a;人脸图像和对应年龄标签&#xff0c;用于年龄估计任务&#xff1b;电梯、楼…

作者头像 李华
网站建设 2026/9/29 15:41:35

非烫火锅加盟口味怎么样,消费者评价如何

行业变迁里的深耕之路火锅餐饮赛道从不缺追逐流量的新面孔&#xff0c;也从不缺被潮水拍走的赶路人。从上世纪九十年代街边巷尾的市井小锅&#xff0c;到如今连锁化、标准化的行业新生态&#xff0c;二十余年的行业浮沉里&#xff0c;有人赚快钱退场&#xff0c;有人沉下心扎根…

作者头像 李华
网站建设 2026/9/29 15:41:18

CTF新手入门实战指南:平台、密码学、杂项与AI辅助

前阵子一个刚入行安全的朋友问我&#xff0c;CTF到底是从哪里开始学。我直接跟他说&#xff0c;别去看那些厚得像字典一样的教材&#xff0c;先找几道CTF题目做一遍再说。很多人觉得CTF是“大神才能玩的东西”&#xff0c;其实恰恰相反&#xff0c;CTF对新手是最友好的一种学习…

作者头像 李华