1. 项目概述与核心价值
在嵌入式网络设备开发中,尤其是在工业控制、车载网关或边缘计算这类对网络性能有严苛要求的场景里,服务质量(QoS)配置从来都不是一个“锦上添花”的选项,而是决定系统能否稳定、可靠运行的关键基石。我们经常遇到这样的困境:一个关键的实时控制报文,可能因为后台大量的文件传输数据而被阻塞在网卡队列里,导致毫秒级的延迟波动,这对于需要确定性的系统来说是不可接受的。传统上,我们依赖Linux内核的纯软件QoS方案,比如
tc
配合
htb
、
pfifo_fast
等队列规则,但这会消耗宝贵的CPU周期,尤其在多端口、高吞吐量的场景下,CPU开销可能成为瓶颈。
NXP的Layerscape系列处理器,特别是像LS1043A、LS1046A这类集成了DPAA1(Data Path Acceleration Architecture 1)架构的芯片,提供了一个优雅的解决方案:将复杂的QoS策略卸载到专用的硬件模块中执行。这其中,CEETM(Customer Edge Egress Traffic Management)模块就是负责出口流量管理的核心硬件引擎。它允许我们通过熟悉的Linux
tc
命令来定义复杂的调度、整形和优先级策略,但实际的队列管理、流量整形计算则由硬件完成,软件只负责下发配置。这意味着极低的CPU占用和近乎线速的QoS处理能力。
然而,官方文档往往侧重于功能罗列和命令参考,对于如何在实际项目中从零开始搭建一套有效的QoS策略,如何理解硬件队列(CQ, Class Queue)与
tc
层级结构的映射关系,以及在配置PFC(Priority-based Flow Control)时如何避开自动协商的“坑”,缺乏系统性的实践解读。本文将结合我多次在LS1043ARDB和LS1046ARDB平台上部署QoS的经验,深入剖析DPAA1 CEETM的配置逻辑,并提供从内核配置、
tc
命令实操到
ethtool
调试的完整指南。无论你是正在评估Layerscape平台网络性能的架构师,还是需要解决具体流量拥塞问题的嵌入式开发工程师,这篇文章都能为你提供可直接落地的参考。
2. DPAA1 QoS架构深度解析:从硬件模块到软件接口
要玩转CEETM,绝不能仅仅停留在照搬
tc
命令的层面。必须理解其背后的硬件架构和设计哲学,这样才能在遇到复杂需求或异常问题时,知道从何处入手分析和调整。
2.1 CEETM硬件架构与核心概念
CEETM本质上是QMan(Queue Manager)的一个子模块,专门负责出口(Egress)方向的流量管理。它的设计目标很明确:为每个FMan(Frame Manager)端口提供一个可编程的、硬件加速的流量调度器。
核心组件与数据流: 想象一下数据包离开CPU、准备从网口发送出去的路径。在DPAA1的世界里,数据包首先被分配到不同的 帧队列(Frame Queues, FQs) 。这些FQs会根据配置,被映射到CEETM管理的**逻辑网络接口(Logical Network Interface, LNI)**上。每个LNI可以理解为一个虚拟的发送端口,与物理端口绑定。
CEETM内部的核心调度单元是 CQ通道(Class Queue Channel) 。每个LNI可以连接多个CQ通道(LS1043A/1046A支持8或32个)。而每个CQ通道内部,又包含了16个 类别队列(Class Queue, CQ) 。这16个CQ的调度规则是CEETM策略的落脚点:
- CQ 0-7 :这8个是独立队列,每个都直接连接到一个严格优先级(Strict Priority)调度器。数字越小,优先级越高。CQ0的流量永远比CQ1优先发送。
- CQ 8-15 :这8个队列可以灵活分组。默认情况下,它们形成一个包含8个队列的 Group A 。但你也可以将其配置为两个组: Group A (CQ8-11) 和 Group B (CQ12-15) 。组内的队列不再遵循严格优先级,而是通过**加权带宽公平调度(WBFS)**算法来共享带宽。你可以为组内的每个CQ设置一个权重(1-248),权重越高,获得的带宽比例越大。
整形(Shaping)与调度(Scheduling)的层次: CEETM的调度是分层级的,这是理解其配置复杂性的关键。
-
CQ通道级调度
:每个CQ通道可以配置为
整形通道(Shaped)
或
非整形通道(Unshaped)
。
- 整形通道 :通道出口有一个双速率整形器(双色或三色标记),可以配置承诺速率(CR)和超额速率(ER)。通道内所有CQ(无论是独立的还是组内的)的流量,都需要先经过这个整形器的管制。
- 非整形通道 :通道没有速率限制,其流量直接进入下一级调度。
-
LNI级调度
:一个LNI上所有通道的流量最终汇聚于此。这里进行最终的调度:
- 所有非整形通道的流量,进入一个**非整形公平队列(uFQ)**进行调度。
- 所有整形通道的流量,先经过一个 整形公平队列(shFQ) 调度,然后再经过一个LN I级别的双速率整形器 (是的,通道和LNI都可以整形)。
- 最后,uFQ的流量(高优先级)、CR整形后的流量(中优先级)、ER整形后的流量(低优先级)经过一个 严格优先级调度器 ,最终被发送出去。
2.2 Linux TC与CEETM的术语映射
Linux的流量控制(
tc
)体系是一个层次化的树状结构,由
队列规则(qdisc)
、**类别(class)
和
过滤器(filter)**构成。CEETM驱动通过一个名为
ceetm
的自定义qdisc,将硬件的层级结构完美地映射到了
tc
的框架下。这张映射表是你配置时的“罗塞塔石碑”:
| CEETM 硬件概念 | Linux TC 对应物 | 说明 |
|---|---|---|
| LNI |
type root
的
qdisc
|
绑定到网络接口(如
fm1-mac3
)的根qdisc。在此配置LNI的总整形器。
|
| CQ通道 |
type root
的
class
|
作为根qdisc的子类创建。在此配置通道是整形(
rate
)还是非整形(
tbl
)。
|
| 独立CQ (0-7) |
type prio
的
qdisc
及其
class
|
在通道class下添加一个
prio
类型的qdisc,其
qcount
参数定义创建几个独立CQ(1-8)。每个生成的class对应一个独立CQ。
|
| CQ组 (Group A/B) |
type wbfs
的
qdisc
及其
class
|
挂载在某个
prio
class下。
qcount
为4或8,对应4或8个CQ的组。
qweight
参数设置组内每个CQ的权重。
|
| 调度与整形策略 |
ceetm
qdisc/class 的
参数
|
通过
rate
/
ceil
配置整形速率,通过
qweight
配置WBFS权重,通过
cr
/
er
布尔值控制CQ是否参与CR/ER整形。
|
| 流量分类 |
tc filter
|
使用
u32
,
flower
等分类器,将数据包标记并引导至对应的
classid
,最终进入特定的硬件CQ。
|
一个关键的心得:
在CEETM的
tc
配置中,
qdisc
和
class
的创建顺序与硬件层级是严格对应的。你必须先创建LNI(根qdisc),然后创建通道(class),再在通道下创建独立CQ(
prio
qdisc)或CQ组(
wbfs
qdisc)。过滤器则需要从根qdisc开始,层层向下添加,确保数据包能被正确分类到每一层,最终到达目标叶子class(即最终的CQ)。
3. 实战前准备:内核配置与基础环境搭建
纸上得来终觉浅,绝知此事要躬行。在开始敲
tc
命令之前,我们必须确保系统底层已经为CEETM做好了准备。
3.1 内核编译选项
DPAA1的CEETM功能不是默认开启的,需要在编译内核时手动配置。以下是在
make menuconfig
或基于此的构建系统(如Yocto的
bitbake -c menuconfig virtual/kernel
)中需要检查的关键选项:
# 1. 启用通用网络QoS支持
Networking support --->
Networking options --->
[*] QoS and/or fair queueing --->
# 至少启用u32分类器,这是最常用的匹配工具
<*> Universal 32bit comparisons w/ hashing (NET_CLS_U32)
# 2. 启用DPAA以太网驱动及CEETM
Device Drivers --->
Network device support --->
Ethernet driver support --->
Freescale/NXP devices --->
<*> Freescale/NXP DPAA Ethernet
# 这个选项是CEETM支持的关键,务必选中
<*> Freescale/NXP DPAA CEETM QoS
选中
Freescale/NXP DPAA CEETM QoS
后,其子选项(如不同速端口的拥塞阈值)通常会变为可见并可配置。通常保持默认值即可,除非你在特定流量模型下遇到了缓冲区问题。
3.2 构建CEETM用户态工具
内核驱动提供了基础设施,但用于配置的
ceetm
qdisc代码通常作为一个独立的内核模块或用户态补丁,在NXP的SDK中是以一个单独的recipe(如
ceetm.bb
)提供的。你需要使用BitBake来编译它:
bitbake ceetm
编译完成后,相关的内核模块(如果以模块形式提供)和
tc
工具的补丁(使
tc
能识别
ceetm
类型)就会被安装到镜像中。请确保你烧录或加载的是包含此工具的内核与根文件系统。
3.3 重要限制与前提条件
在兴奋地开始配置之前,务必牢记以下几点,它们能帮你避开很多“为什么不起作用”的坑:
-
仅限私有以太网接口
:CEETM目前仅支持DPAA1的**私有以太网(Private Ethernet)**接口,即
fm1-macX这类接口。对于共享的(Shared)或虚拟的接口可能不支持。 -
不支持绑定接口
:你不能在Linux Bonding接口上直接应用
ceetmqdisc。QoS策略需要应用到每个物理的fm1-macX接口上。 -
PCD配置先行
:DPAA1的数据路径由FMan(Frame Manager)驱动,其基础配置(如缓冲区池、帧队列分配)由PCD(Parse-Classify-Distribute)策略文件定义。在应用复杂的
tc规则前, 必须 确保正确的PCD配置已经通过fmc工具加载。通常,板级支持包(BSP)会提供默认的PCD配置文件,位于/etc/fmc/config/目录下。使用fmc -c <config.xml> -p <policy.xml> -a命令加载它们。 -
理解
overhead参数 :在配置整形器(rate)时,overhead参数至关重要。它用于补偿物理层和链路层的额外开销,如帧间隔(IFG)、前导码和帧校验序列(FCS)。官方文档推荐值为24(即12字节IFG + 8字节前导码 + 4字节FCS)。 忽略或错误设置此参数会导致实际速率严重偏离预期 。例如,你想限制到100Mbps,但实际可能只能达到~94Mbps。
4. CEETM QoS配置实战:从基础限速到复杂调度
下面我们通过四个由浅入深的例子,来具体看看如何将理论转化为实际的
tc
命令。我们假设操作对象是
fm1-mac3
接口。
4.1 案例一:基础双流速率限制
场景 :我们有两个重要的TCP应用流,分别跑在目标端口80(HTTP)和21(FTP)上。我们希望限制端口80的流量不超过150Mbps,端口21的流量不超过850Mbps,而物理端口是1Gbps。
配置思路 :
-
在接口上创建根
ceetmqdisc,并启用LNI级别的整形器,将总速率设为1Gbps(rate 1000mbit)。 -
创建两个
整形通道
(
type root的class),分别设置其CR为150Mbps和850Mbps。 -
在每个通道下,创建
prioqdisc来生成独立的CQ(这里每个通道只需要1个CQ)。 -
使用
tc filter基于目标端口进行分类,将流量导入对应的通道和CQ。
实操命令与解析:
# 1. 添加根qdisc,启用LNI整形器。handle 1: 是此qdisc的句柄。
# `overhead 24` 是关键,用于补偿物理层开销。
tc qdisc add dev fm1-mac3 root handle 1: ceetm type root rate 1000mbit overhead 24
# 2. 创建第一个整形通道,承诺速率150Mbps。其父为根qdisc(1:),自己的classid为1:1。
tc class add dev fm1-mac3 parent 1: classid 1:1 ceetm type root rate 150mbit
# 3. 创建第二个整形通道,承诺速率850Mbps。classid为1:2。
tc class add dev fm1-mac3 parent 1: classid 1:2 ceetm type root rate 850mbit
# 4. 在通道1:1下创建优先级调度器,只生成1个队列(CQ)。handle 2: 是这个prio qdisc的句柄。
tc qdisc add dev fm1-mac3 parent 1:1 handle 2: ceetm type prio qcount 1
# 5. 在通道1:2下创建优先级调度器,只生成1个队列。
tc qdisc add dev fm1-mac3 parent 1:2 handle 3: ceetm type prio qcount 1
# 6. 添加过滤器,将目标端口80的流量引导至通道1:1。
# 第一层过滤:在根qdisc(1:)上,将流量分类到通道1:1。
tc filter add dev fm1-mac3 parent 1: prio 1 protocol ip u32 match ip dport 80 0xffff flowid 1:1
# 第二层过滤:在通道1:1的prio qdisc(2:)上,将流量分类到其唯一的叶子class 2:1。
# 注意:`prio` qdisc会自动创建子类,命名规则为`[qdisc句柄]:1`到`[qdisc句柄]:[qcount]`。
tc filter add dev fm1-mac3 parent 2: prio 1 protocol ip u32 match ip dport 80 0xffff flowid 2:1
# 7. 添加过滤器,将目标端口21的流量引导至通道1:2。
tc filter add dev fm1-mac3 parent 1: prio 1 protocol ip u32 match ip dport 21 0xffff flowid 1:2
tc filter add dev fm1-mac3 parent 3: prio 1 protocol ip u32 match ip dport 21 0xffff flowid 3:1
关键点与避坑指南:
-
过滤器层级
:必须为每一层
qdisc都添加过滤器。根过滤器的flowid指向通道class,通道内prio过滤器的flowid指向其叶子class。缺少任何一层,数据包都无法到达最终的硬件CQ。 -
flowid的指定 :flowid必须与classid完全匹配。prioqdisc自动生成的子类classid就是其handle加冒号和序号(如2:1)。 - 速率总和 :两个通道的CR总和(150+850=1000Mbps)等于LNI的CR。这是一种典型的管道模型,确保了带宽的硬性划分。
4.2 案例二:同一通道内的严格优先级调度
场景 :端口80(HTTP)和端口21(FTP)的流量共享同一个850Mbps的通道,但HTTP流量需要绝对优先于FTP流量发送。
配置思路 :
- 创建一个总速率为1Gbps的LNI和一个850Mbps的整形通道(剩余150Mbps可能预留给其他流量)。
-
在该通道下创建一个
qcount=2的prioqdisc,这会生成两个独立CQ(CQ0和CQ1)。 -
通过过滤器,将高优先级的HTTP流量(端口80)导向
2:1(对应更高优先级的CQ0),将FTP流量(端口21)导向2:2(对应较低优先级的CQ1)。
实操命令:
# 1. 创建根qdisc和整形通道
tc qdisc add dev fm1-mac3 root handle 1: ceetm type root rate 1000mbit overhead 24
tc class add dev fm1-mac3 parent 1: classid 1:1 ceetm type root rate 850mbit
# 2. 在通道内创建包含2个优先级队列的调度器
tc qdisc add dev fm1-mac3 parent 1:1 handle 2: ceetm type prio qcount 2
# 3. 分类流量:端口80到最高优先级队列(2:1),端口21到次优先级队列(2:2)
tc filter add dev fm1-mac3 parent 1: prio 1 protocol ip u32 match ip dport 80 0xffff flowid 1:1
tc filter add dev fm1-mac3 parent 2: prio 1 protocol ip u32 match ip dport 80 0xffff flowid 2:1
tc filter add dev fm1-mac3 parent 1: prio 2 protocol ip u32 match ip dport 21 0xffff flowid 1:1
tc filter add dev fm1-mac3 parent 2: prio 2 protocol ip u32 match ip dport 21 0xffff flowid 2:2
效果验证 :当两个流同时以超过850Mbps的速率发送时,端口80的流会完全占用带宽,直到其空闲,端口21的流才能开始发送。这就是严格优先级调度的体现。
4.3 案例三:使用WBFS实现加权公平���宽分配
场景 :我们有四个不同的数据流(例如,来自四个不同的服务器或应用),它们需要共享一个1Gbps的通道,但不是平均分配,而是按照 10:5:2:1 的比例分配带宽。
配置思路 :
- 创建LNI和整形通道。
-
在通道下创��一个
prioqdisc,但这次我们只生成1个独立CQ(qcount=1),这个CQ将作为“锚点”。 -
在这个独立的CQ(
prio class)下,挂载一个type wbfs的qdisc,并设置qcount=4来创建一个包含4个CQ的组。 -
通过
qweight参数为组内的4个CQ分别设置权重,例如 200, 100, 40, 20(比例约为10:5:2:1)。 - 用过滤器将不同的流量(例如通过不同的目标端口区分)导向WBFS组内的不同CQ。
实操命令:
# 1. 创建根qdisc和整形通道
tc qdisc add dev fm1-mac3 root handle 1: ceetm type root rate 1000mbit overhead 24
tc class add dev fm1-mac3 parent 1: classid 1:1 ceetm type root rate 1000mbit
# 2. 创建1个独立CQ作为“锚点”,句柄为2:
tc qdisc add dev fm1-mac3 parent 1:1 handle 2: ceetm type prio qcount 1
# 3. 在锚点CQ(2:1)下创建一个4队列的WBFS组,并设置权重。句柄为3:
# `cr 1 er 1` 表示该组内的队列同时参与CR和ER整形(默认值,可省略)。
tc qdisc add dev fm1-mac3 parent 2:1 handle 3: ceetm type wbfs qcount 4 qweight 200 100 40 20
# 4. 添加过滤器,将不同端口的流量分类到WBFS组内的不同队列。
# 假设端口10001的流获得最高权重(200),导向3:1
tc filter add dev fm1-mac3 parent 1: prio 1 protocol ip u32 match ip dport 10001 0xffff flowid 1:1
tc filter add dev fm1-mac3 parent 2: prio 1 protocol ip u32 match ip dport 10001 0xffff flowid 2:1
tc filter add dev fm1-mac3 parent 3: prio 1 protocol ip u32 match ip dport 10001 0xffff flowid 3:1
# 端口10002的流获得权重100,导向3:2
tc filter add dev fm1-mac3 parent 1: prio 2 protocol ip u32 match ip dport 10002 0xffff flowid 1:1
tc filter add dev fm1-mac3 parent 2: prio 2 protocol ip u32 match ip dport 10002 0xffff flowid 2:1
tc filter add dev fm1-mac3 parent 3: prio 2 protocol ip u32 match ip dport 10002 0xffff flowid 3:2
# ... 以此类推为端口10003和10004添加过滤器,分别导向3:3和3:4
注意事项 :WBFS算法是工作在 组内 的。只要组内有任意队列有数据包,调度器就会按照权重比例从各个队列中取出数据包发送。权重是相对值,系统会根据总和进行归一化。
4.4 案例四:非整形通道的公平队列(uFQ)
场景 :在两个非整形的通道间实现公平队列调度。例如,设备作为路由器,有两个上游流量需要转发到同一个1G下行链路,我们希望它们能公平竞争(或按权重竞争)带宽,而不是对其进行硬性速率限制。
配置思路 :
-
创建根qdisc时,
不指定
rate参数 ,这意味着LNI级别的整形器被禁用,所有通道进行非整形调度。 -
创建
type root的class时,使用tbl(Token Bucket Limit)参数代替rate。tbl值影响uFQ算法的“权重”,值越大,在一次轮询中能发送的数据量可能越多,但其公平性算法与整形通道的shFQ不同。 -
后续的
prioqdisc和过滤器配置与整形通道类似。
实操命令:
# 1. 添加根qdisc,不启用整形(无rate参数)
tc qdisc add dev fm1-mac3 root handle 1: ceetm type root
# 2. 添加两个非整形通道,通过tbl设置权重。tbl值越大,潜在带宽份额可能越高。
tc class add dev fm1-mac3 parent 1: classid 1:1 ceetm type root tbl 1000
tc class add dev fm1-mac3 parent 1: classid 1:2 ceetm type root tbl 500
# 3. 为每个通道创建独立的CQ
tc qdisc add dev fm1-mac3 parent 1:1 handle 2: ceetm type prio qcount 1
tc qdisc add dev fm1-mac3 parent 1:2 handle 3: ceetm type prio qcount 1
# 4. 分类流量(例如基于源IP或DSCP值)
tc filter add dev fm1-mac3 parent 1: prio 1 protocol ip u32 match ip src 192.168.1.100/32 flowid 1:1
tc filter add dev fm1-mac3 parent 2: prio 1 protocol ip u32 match ip src 192.168.1.100/32 flowid 2:1
tc filter add dev fm1-mac3 parent 1: prio 2 protocol ip u32 match ip src 192.168.1.101/32 flowid 1:2
tc filter add dev fm1-mac3 parent 3: prio 2 protocol ip u32 match ip src 192.168.1.101/32 flowid 3:1
核心区别
:在非整形模式下,
tbl
参数控制的是uFQ算法中令牌桶的深度,它影响了队列在每次被调度时能连续发送的数据量上限,从而间接影响带宽分配的“平滑度”和公平性。与整形模式的硬性速率上限不同,这是一种基于竞争的公平调度。
5. PFC配置与ethtool监控实战
除了出口的CEETM,入口的流量控制同样重要,尤其是在与支持数据中心桥接(DCB)特性的交换机互连时。基于优先级的流量控制(PFC)允许在以太网链路层针对不同的优先级队列进行暂停帧控制,从而实现无损传输。
5.1 使用ethtool配置与查看PFC
在DPAA1驱动中,PFC功能通过标准的
ethtool
接口暴露。
查看当前PFC状态:
ethtool -a fm1-mac3
输出会显示接收(RX)和发送(TX)方向上,PFC帧的启用状态是
on
还是
off
。
启用/禁用PFC:
# 启用RX方向的PFC
ethtool -A fm1-mac3 rx on
# 禁用TX方向的PFC
ethtool -A fm1-mac3 tx off
# 同时控制RX和TX
ethtool -A fm1-mac3 rx on tx on
5.2 自动协商(Autonegotiation)的巨坑
这是配置PFC时最容易出错的地方,官方文档也做了特别强调,但实践中仍常被忽略。
-
当自动协商启用时(默认)
:
ethtool -A命令 不会直接 触发本端发送PFC帧。它只是设置了本端的 本地能力 。是否实际发送PFC帧,取决于链路两端的PFC能力协商结果。你需要通过ethtool的-p参数或专用DCB工具(如lldptool)来通告本端的PFC能力。如果对端设备不支持或不匹配你的PFC配置,你本地的ethtool -A设置可能完全无效。 -
当自动协商关闭时
:
ethtool -A的设置会直接生效,覆盖链路协商的结果。这在和对端设备进行静态配置时比较有用。
操作建议:
-
首先,使用
ethtool -a查看当前状态和自动协商是否开启。 - 如果需要对端配合,确保交换机侧也正确配置了PFC,并且优先级映射一致。
-
如果希望强制本端行为,可以考虑先关闭自动协商(需谨慎,可能影响链路其他参数),再设置PFC。
ethtool -A fm1-mac3 autoneg off ethtool -A fm1-mac3 rx on tx on -
更常见的做法是在启用自动协商的情况下,结合使用
lldptool来发布DCB TLV,与交换机进行能力协商。
5.3 利用ethtool进行深度调试
ethtool -S
命令是DPAA1驱动调试的利器,它能提供丰富的硬件统计信息。
ethtool -S fm1-mac1
关键统计信息包括:
-
interrupts [CPU x]: 每个CPU核心处理的中断数,用于观察中断均衡。 -
rx/tx packets [CPU x]: 每个CPU核心收发的数据包数,结合PCD配置,可分析流量是否按预期被分配到不同的核心关联队列(Core Affined Queues)。 -
tx confirm: 发送确认数,应与发送包数匹配。 -
tx error: 发送错误计数,非零值通常指示问题(如DMA错误、缓冲区不足)。
一个实战技巧
:在配置了复杂的PCD策略和CEETM QoS后,如果发现性能不佳或丢包,首先查看
ethtool -S
的输出。如果某个CPU核心的
rx packets
异常高,而其他核心很低,可能是流量没有均匀分布,导致单个核心成为瓶颈。这时需要回顾你的PCD分类策略,确保流量被哈希到不同的核心关联帧队列(FQID)上。文档中给出的FQID基地址公式
((MAC register address) & 0x1fffff) >> 6
和表格,就是用来计算这些队列ID,以便在PCD配置文件中进行精确绑定的。
6. 常见问题排查与性能调优心得
即使按照指南操作,在实际部署中也可能遇到各种问题。以下是我总结的一些常见故障点及排查思路。
6.1 配置不生效或流量未被正确分类
-
症状
:
tc命令执行成功,但流量似乎没有按规则被限速或调度。 -
排查步骤
:
-
检查过滤器
:使用
tc filter show dev fm1-mac3逐级检查过滤器是否被正确添加。确保从根qdisc到叶子class的每一层都有匹配的过滤器。 -
验证分类器匹配
:
u32匹配规则可能因报文结构(如VLAN标签、IP选项)而不匹配。使用tcpdump抓取实际流量,确认报文的五元组与你配置的match条件一致。可以考虑使用更灵活的flower分类器(如果内核支持)。 -
确认PCD配置
:CEETM处理的是已经由FMan分配好并送入相应队列的帧。如果PCD配置错误,流量可能根本没有进入你配置的CEETM所管理的队列。确保
fmc工具已加载正确的配置文件,并且策略与你预期的流量路径匹配。 -
查看统计信息
:一些高级的
tc工具或驱动可能提供队列统计。也可以尝试通过ethtool -S观察发送计数,或使用dropwatch等工具查看是否有丢包发生在QoS模块。
-
检查过滤器
:使用
6.2 启用整形后速率严重不达标
-
症状
:设置了
rate 100mbit,但实际iperf测试只有90-95Mbps。 -
原因与解决
:
-
overhead参数缺失或错误 :这是最常见的原因。务必在根qdisc和所有整形通道的rate配置后加上overhead 24。 -
测量方式问题
:
iperf默认测试的是TCP吞吐量,受TCP窗口、往返时延(RTT)影响。对于极限速率测试,建议使用UDP模式(-u)并指定带宽(-b)。同时,确保测试环境没有其他瓶颈(如对端设备性能、交换机限速)。 -
令牌桶参数
:CEETM使用的是双速率三色标记器,其行为还受到承诺突发大小(CBS)和超额突发大小(EBS)的影响。虽然
tc ceetm接口没有直接暴露这些参数(它们可能有硬件默认值),但在极端突发流量下可能影响瞬时速率。
-
6.3 系统资源耗尽或出现丢包
-
症状
:在高负载下,系统出现内存不足错误,或
ethtool -S显示tx error增加。 -
排查与调优
:
- 缓冲区池(Buffer Pool)大小 :DPAA1驱动使用预分配的缓冲区池。如果整形速率设置得很低,而突发流量很大,数据包会在队列中积压,消耗大量缓冲区。需要检查并可能增大FMan的缓冲区池配置(在PCD配置文件中调整)。
-
队列长度
:虽然CEETM的队列深度主要由硬件决定,但软件层面的
txqueuelen(通过ifconfig设置)也可能有影响。可以适当增加。 -
拥塞控制阈值
:在
内核配置
阶段提到的
FSL_DPAA_CEETM_CCS_THRESHOLD_1G/10G选项,定义了何时认为队列进入拥塞状态。如果默认值在你的流量模型下导致过早或过晚触发拥塞控制,可以进行调整。阈值设置太小会导致不必要的丢包,太大会导致缓冲区积压。
6.4 配置的持久化
通过
tc
命令进行的配置在重启后会丢失。对于产品化部署,你需要将配置脚本化,并放入系统的启动流程中(如
/etc/rc.local
或创建systemd service)。一个可靠的实践是,在脚本开头先清除接口上所有现有的
tc
配置:
tc qdisc del dev fm1-mac3 root
,然后再重新添加你的规则,这样可以避免残留配置的干扰。
最后,CEETM的硬件能力远不止本文介绍的这些基础场景。它支持更复杂的层次结构、双速率整形中的
ceil
(超额速率)设置、以及
cr
/
er
标志对流量颜色的精细控制。当你需要实现诸如“保证带宽+允许突发”、“区分绿色/黄色数据包”等高级策略时,这些高级功能就会派上用场。建议在掌握基础后,仔细研读
tc qdisc add ceetm help
的输出和平台参考手册,进行更深入的探索。

146


被折叠的 条评论
为什么被折叠?



