3. DPAA数据通路解析

DPAA(Data Path Acceleration Architecture)是 Layerscape 处理器中把网络报文处理从 CPU 卸载到硬件加速器的核心框架。它由三个协同工作的硬件模块构成:BMan(Buffer Manager,缓冲管理器)负责缓冲区池的分配与回收,FMan(Frame Manager,帧管理器)负责报文的接收、解析、分类与发送,QMan(Queue Manager,队列管理器)负责帧描述符的排队、调度与分发。理解这三者的分工与数据流,是后续做多核报文分发、零拷贝和队列调优的基础。

三个模块的角色分工

BMan 管理的是“内存缓冲区”,而不是报文本身。它维护若干 Buffer Pool,每个池由软件预先填充一定数量的缓冲区(典型大小 256B、1KB、2KB 等)。当 FMan 收到一个以太网帧时,它并不自己申请内存,而是向 BMan 请求一个缓冲区,把帧数据 DMA 写入其中。缓冲区用完后,由消费者(CPU 或加速器)通过释放命令归还给 BMan,实现循环复用。BMan 的价值在于把“分配/回收”这一高频操作硬件化,避免 CPU 反复调用内存分配器。

FMan 是报文进出的门户。接收方向上,它从 MAC/PHY 拿到比特流,完成帧定界、CRC 校验、可选的帧解析(Parse)、分类(Classify)和分发(Distribute),然后生成一个帧描述符(Frame Descriptor,FD),把描述符送入 QMan 的某个队列。发送方向上,FMan 从 QMan 取出发送队列中的 FD,读取缓冲区里的帧数据,经 MAC 发出。FMan 内部还有多个离线解析引擎(Offline Parsing Engine,OA)和主机命令引擎(Host Command,HC),用于处理需要 CPU 介入的慢路径报文。

QMan 是调度中枢。它管理大量队列(Frame Queue,FQ)和队列组(Work Queue,WQ),每个 FQ 可以绑定到某个 WQ 或某个 CPU 的通道(Channel)。QMan 支持基于优先级的调度、队列拥塞控制(Congestion Group)、尾丢弃(Tail Drop)以及“保持顺序”的帧推送。CPU 通过门铃(Doorbell)向 QMan 提交入队/出队命令,QMan 则通过专用中断或轮询方式把 FD 推送给 CPU。

BMan 缓冲管理器 Pool 0 (256B) Pool 1 (1KB) Pool 2 (2KB) 分配 / 回收缓冲区 FMan 帧管理器 MAC / PHY 接口 帧解析 Parse / 分类 Classify 分发 Distribute 收帧 / 发帧 / 生成 FD QMan 队列管理器 Frame Queue (FQ) Work Queue (WQ) 调度 / 拥塞控制 FD 入队 / 出队 / 分发 请求缓冲区 FD 入队 发送 FD CPU 核心 (ARM64) 门铃 Doorbell / 中断 / 轮询 处理 FD → 读取缓冲区数据 FD 推送 / 出队响应 入队 / 释放命令 释放缓冲区 数据流:MAC 收帧 → FMan 解析分类 → 向 BMan 取缓冲区写入数据 → 生成 FD 入 QMan 队列 → QMan 调度推送给 CPU 发送流:CPU 构造 FD 入 QMan 发送队列 → FMan 取出 FD → 从缓冲区读帧数据 → MAC 发出 → 缓冲区归还 BMan 注:FD(Frame Descriptor)描述帧的缓冲区地址、长度、解析结果和队列信息,是三个模块之间传递的核心数据结构。

队列调度机制

QMan 的调度核心是 FQ 到 WQ 的映射。每个 FQ 有一个 FQID,软件在初始化时把 FQID 绑定到某个 WQ 或某个 CPU 的专用通道。当 FMan 把 FD 入队到某个 FQ 后,QMan 根据该 FQ 的调度配置决定何时把 FD 推送给消费者。调度配置包括:优先级(同一 WQ 内多个 FQ 的竞争顺序)、权重(加权轮询时的带宽比例)、拥塞组(当队列积压超过阈值时触发尾丢弃或流控)。

一个典型的多核场景是:4 个 CPU 核心各自绑定一个 WQ,FMan 根据 RSS(Receive Side Scaling)哈希把不同流的 FD 分发到不同 FQ,每个 FQ 再映射到对应核心的 WQ。这样同一 TCP 流始终由同一核心处理,既保证顺序又实现负载均衡。如果某个核心过载,可以通过调整 FQ 到 WQ 的映射或修改权重来重新分配。

帧解析与分类

FMan 的解析引擎会逐层剥离报文头部:以太网头、VLAN 标签、IPv4/IPv6 头、TCP/UDP 头,提取五元组、协议号、ToS/DSCP 等字段。分类引擎根据这些字段匹配预置的规则(类似 ACL),决定该帧进入哪个 FQ。解析结果会写入 FD 的 Parse Result 区域,CPU 拿到 FD 后无需重新解析即可直接读取五元组,这是 DPAA 零拷贝和快速转发的重要前提。

实践提示:在配置 FQ 时,FQID 的分配需要与 FMan 的 Port/Class 配置一致。常见做法是:每个以太网口分配一段连续的 FQID 范围,接收默认队列、错误队列、慢路径队列分别使用不同 FQID,便于后续用 fmlib 或 dpa_app 工具观察队列计数。

缓冲区池的规划

BMan 的 Pool 大小和数量直接影响吞吐。若 Pool 太小,FMan 收帧时取不到缓冲区就会丢包;若 Pool 太大,则浪费内存。经验做法是:按“最大并发帧数 × 1.5”估算每个 Pool 的缓冲区数量。例如 1Gbps 线速、平均帧长 512B 时,最大并发帧数约为 1e9 / (512×8) ≈ 244k,但实际硬件队列深度有限,通常配置 8k~32k 个缓冲区即可满足突发。Pool 的缓冲区大小应覆盖最大帧长(含 VLAN 和可能的隧道封装),否则需要多缓冲区链(Scatter/Gather)。

收发包的完整路径

以接收为例:PHY 收到信号 → MAC 完成帧定界和 CRC → FMan 解析引擎提取头部 → 分类引擎匹配规则 → FMan 向 BMan 请求缓冲区 → DMA 写入帧数据 → 生成 FD(含缓冲区地址、长度、解析结果、目标 FQID)→ FD 入 QMan 的 FQ → QMan 按调度策略推送到 CPU 的 WQ → CPU 读取 FD 和缓冲区数据 → 处理完成后释放缓冲区回 BMan。发送路径则是反向:CPU 构造 FD 入发送 FQ → QMan 调度 → FMan 取出 FD → 从缓冲区读数据 → MAC 发送 → 缓冲区释放。