DPDK 教程(三):多队列 + RSS + 多 worker 的最小转发 / Echo

DPDK 教程(三):多队列 + RSS + 多 worker 的最小转发 / Echo

本文对应学习路径第三步:在理解 ethdev/mbuf/mempool 后,做一个最小可运行 的转发或 echo 原型,刻意使用 多 RX 队列 + RSS 把流量分散到 多个 worker lcore 。目标是建立 "队列---核---数据面线程模型" 的设计直觉,而不是追求功能最全的 L3 转发器。


本文目标与验收标准

  • 目标 :同一端口(或双端口)上启用 >=2 个 RX 队列 ,配置 RSS 使多流分散到不同队列;每个队列绑定一个 worker lcore 做最小处理(echo 或 L2 环回/交换)。
  • 验收 :用 pktgen-dpdk 或双口环回产生多流 (不同五元组)时,rte_eth_statstestpmd/fwd 统计显示 各队列均有收包;CPU 利用率在多核上呈扩展趋势(受限于 PCIe/NIC/内存带宽时除外)。

设计选择:先 testpmd 原型,再落到最小 C 程序

为什么分两步

  • testpmd 能快速验证 RSS hash、队列数、reta( redirection table ) 与 PMD 能力矩阵,减少"自写程序配置错"的变量。
  • 最小 C 程序 强迫你补齐 EAL init、port configure、queue setup、lcore launch 全链路。

第一部分:RSS 与多队列在解决什么问题

场景

  • 单队列 + 单核收包容易 CPU 单线程瓶颈;NIC 已具备多队列 DMA 能力。

RSS(Receive Side Scaling)在做什么

  • NIC 对报文计算 hash(常见输入为四元组/五元组,具体算法与字段由硬件与配置决定)。
  • 用 hash 结果查 RETA(redirection table) 选择 RX queue index
  • 目标:让不同流 落到不同队列 ,从而被不同 worker 并行处理。

你必须接受的限制(严谨)

  • 单流 无法被 RSS "拆成多核并行";扩展性来自多流
  • RSS hash 与 key、RETA、对称性 (是否支持 symmetric RSS)高度依赖 NIC 与 PMD;跨平台移植要重新验证。

第二部分:端口与队列配置(API 心智图)

典型顺序(与教程二一致,这里强调多队列):

  • rte_eal_init()
  • rte_eth_dev_configure(port_id, nb_rx_queue, nb_tx_queue, &port_conf)
    • port_conf.rx_adv_conf.rss_conf:启用 RSS、指定 rss_hf(hash 类型位掩码,随 ethdev 演进)。
  • 对每个 qrte_eth_rx_queue_setup(port, q, nb_rxd, socket, &rxconf, pool_q)
    • 常见做法 :每队列一个 mbuf pool(减少争用)或共享 pool(省内存);取舍见文末。
  • rte_eth_dev_start()

RETA 配置

  • 使用 rte_eth_dev_rss_reta_update()(或版本等价 API)把 queue id 写入 RETA 表项。
  • 初学者可先用 均匀映射:hash 桶轮流指向各队列。

第三部分:多 worker 线程模型

典型拓扑

  • 1× main lcore:负责初始化、打印、信号处理(视应用)。
  • N× worker :每个 worker 绑定一个 RX queue (常见为 queue_id == worker_index),循环:
text 复制代码
while (running) {
    nb = rte_eth_rx_burst(port, queue_id, pkts, BURST_SIZE);
    for (i = 0; i < nb; i++) {
        /* echo: swap eth addrs or just count */
        /* minimal forward: send to tx_port/tx_queue */
    }
    rte_eth_tx_burst(tx_port, tx_queue, pkts, nb); /* 注意返回值与 mbuf 生命周期 */
}

并发与 mempool 标志(正确性)

  • 多个 worker 同时从同一 mempool 分配/释放 :需 MP/MC 或确认 PMD/应用侧不会并发触达同一无锁假设。
  • 每队列独立 pool 且每队列仅单 worker 使用:可用更激进的 SP/SC 配置(前提:全链路无其他核触碰该 pool)。

第四部分:最小 Echo vs 最小 L2 Forward

Echo(单端口常见)

  • 含义 :把收到的包从 同一端口 TX 回去(实验室常用;生产需考虑 MAC 交换学习与风暴)。
  • 最小改动:交换以太网 SA/DA 或保持原样(取决于对端是否能接受环回帧)。

L2 forward(双端口常见)

  • 含义port0 RX -> port1 TX,反之亦然(类似 testpmd 的 mac 转发模式思想)。

TX 侧最容易踩的坑(必读)

  • rte_eth_tx_burst() 返回值 < nb 时:未发送的 mbuf 指针仍有效 ,需要 重试或释放;否则泄漏。
  • TX 队列与 worker 映射要一致:多 worker 多 TX queue 时避免无序锁竞争(或采用集中 TX,但集中 TX常成为瓶颈)。

testpmd 先做能力验证(建议命令族)

具体子命令随 testpmd 版本变化;请以 help 输出为准。下面给学习方向而非保证逐字兼容的脚本。

  • 查看端口 RSS 能力:show port rx_rss_hash(或等价命令)
  • 配置 hash 字段:port config all rss ip / rss all(示例)
  • 配置转发模式:set fwd macswap / io
  • 观察队列统计:show port stats all 与 per-queue 统计(若 PMD 支持)

当你确认 多队列 + RSStestpmd 下行为正确,再写 C 程序对照复现。


第五部分:最小 C 程序结构(骨架级,避免绑定某版本 API)

建议你自己新建 minimal_fwd.c,按以下模块拆分文件内函数:

  • parse_args():PCI allowlist、队列数、端口模式
  • init_port()dev_configure + RSS + rx/tx_queue_setup
  • init_mempools():每队列 pool 或共享 pool
  • launch_workers()rte_eal_remote_launch(worker_main, arg, lcore)
  • signal_handler():优雅退出,force_quit 标志

不要复制粘贴大段 l3fwd :第三步目标是 结构清晰,不是功能多。


性能与正确性检查清单

  • NUMAport/socket/mempool/lcore 同节点。
  • link/partner:对端是否能接收环回帧;VLAN/MPLS 是否影响 RSS 输入字段。
  • 统计rte_eth_stats_get() 观察 imissed、rx_nombuf、errors(字段名随版本略有差异)。

与教程(四)的衔接

当你能稳定跑多队列转发后,再引入:

  • 硬件 offload(checksum/TSO)减少每包 CPU。
  • flow API 做精确分流(相对 RSS 更可控)。
  • IOVA 模式profiling 解释"为什么某一核打满"。

参考

  • DPDK Sample Applicationsl2fwdl3fwd(对照读,不要第一步就 fork 全部)。
  • DPDK Programmer's Guide:RSS、Ethdev、Multi-process(若你未来要拆控制面)。

RSS/RETA 的具体可用位与默认 key 以你的 NIC datasheet + DPDK PMD release notes 为准;不要在不同代网卡间假设 hash 行为一致。

相关推荐
AI科技星1 小时前
全域数学·体积与表面积通项定理【乖乖数学】
人工智能·算法·数学建模·数据挖掘·机器人
Yingjun Mo1 小时前
1. 在线学习引言
学习·算法
李日灐1 小时前
< 12 > Linux进程:进程虚拟地址空间机制 —— 内存管理的美学
linux·运维·算法
Mr_pyx1 小时前
LeetCode 226. 翻转二叉树(多种解法详解)
算法·深度优先
qeen871 小时前
【算法笔记】各种常见排序算法详细解析(上)
c语言·数据结构·c++·学习·算法·排序算法
绿蕉1 小时前
自动驾驶技术的演进之路:从规则算法到端到端架构
算法·架构·自动驾驶
Ulyanov1 小时前
《从质点到位姿:基于Python与PyVista的导弹制导控制全栈仿真》: 基石——3-DOF质点弹道的高保真建模与数值稳定性分析
开发语言·python·算法·ui·系统仿真
一条大祥脚1 小时前
蚁群算法(例题TSP问题)
算法
青山师1 小时前
数组与链表深度解析:从内存布局到工业级实践
数据结构·算法·链表·数组·算法与数据结构