Skip to content

第 4 周:RoCEv2 报文、GID、MTU 与 QoS 分类

对应原计划:plans/muxi-fabric-network-learning-plan.md 第 4 周。
相关工程:plans/muxi-fabric-probe.md 的 W3 QoS、拥塞控制与 ECMP。
本章定位:理解 RoCEv2 为什么既是 RDMA,又会受到 IP/UDP、ECMP、DSCP/ECN、MTU 和交换机 QoS 的影响。


0. 这一周到底学什么

第 3 周你学了 RDMA verbs 和 RNIC 对象。第 4 周要把这些对象放进以太网数据中心网络里:

RoCEv2 报文到底长什么样?端点设置的 GID、MTU、Traffic Class,如何变成交换机能看到和处理的 header?

学完你要能回答:

  • RoCEv2 为什么使用 IP/UDP 封装?
  • GID index 选择会影响什么?
  • MTU 不一致为什么可能表现为“能连但慢”?
  • MCCL_IB_TC 这类变量如何可能映射到 DSCP/ECN?
  • DSCP、ECN、PCP、priority、PG、TC、queue 分别在哪一层?
  • 为什么端点设置了 TC,不代表交换机就按预期 QoS 处理?
  • 为什么 tcpdump 抓不到 CE/CNP/PFC,不能证明它们没发生?

本周最重要的链路是:

text
MCCL / RDMA 变量

RNIC 生成 packet header

IP DSCP / ECN 或 VLAN PCP

switch trust mode

priority / PG / TC / queue

PFC / ECN / scheduler / buffer

任何一段未知,都不能闭环 QoS 机制。


1. RoCEv2 报文心智图

RoCE = RDMA over Converged Ethernet。

RoCEv1 更偏二层,RoCEv2 跑在 UDP/IP 上。第 4 周主要关心 RoCEv2。

一个简化 RoCEv2 packet:

text
Ethernet header
  ├─ src MAC
  ├─ dst MAC
  ├─ VLAN tag / PCP(如果有)
  └─ EtherType
IP header
  ├─ src IP
  ├─ dst IP
  ├─ DSCP
  ├─ ECN
  └─ TTL / Hop Limit
UDP header
  ├─ src port
  └─ dst port
RoCE / IB transport header
  ├─ opcode
  ├─ QP number
  ├─ PSN
  └─ flags
Payload

为什么这很重要?

因为交换机通常不理解“这是 AllReduce 的第几个 chunk”,它看到的是:

text
MAC / VLAN / IP / UDP / DSCP / ECN / queue

所以通信库变量要影响网络行为,必须最终体现在这些 header 或交换机配置里。


2. GID 和 GID index

2.1 GID 是什么

GID = Global Identifier,是 RDMA/RoCE 端点地址。一个 RDMA 端口可能有多个 GID entry。

这些 entry 可能对应:

text
不同 IP;
不同 RoCE version;
不同 VLAN;
不同 netns / interface;
不同 link local / global 地址。

2.2 GID index 是什么

GID table 像一个数组:

text
index 0 → gid A
index 1 → gid B
index 2 → gid C
...

MCCL_IB_GID_INDEX=5 这类变量就是告诉通信库/RNIC 选哪个 entry。

2.3 GID index 错会怎样

可能表现:

text
不能建连;
建连但走错网络;
走控制面而不是 RoCE 数据面;
某些节点能通某些节点不能通;
性能异常;
QoS/TC 不按预期生效。

2.4 小 case:GID index 是实验变量,不是背景常量

如果实验 A 用 GID index 5,实验 B 由于环境变量缺失或脚本差异用默认 GID index,那么两个实验可能不是同一条数据面路径。

所以 manifest 里必须记录:

text
HCA list
GID index
interface/IP
RoCE version
MCCL/NCCL 相关环境变量

否则后面对比没有意义。


3. MTU:能建连不等于最优性能

3.1 MTU 是什么

MTU 控制单个二层/三层 packet 的最大载荷大小。常见以太网 MTU 是 1500,数据中心/RDMA 场景可能使用 jumbo frame,例如 9000。

3.2 MTU 不一致可能怎样

路径上 MTU 不一致,可能表现为:

text
直接不能建连;
小消息正常,大消息异常;
能跑但吞吐低;
重传、丢包或错误增加;
某些路径正常,某些路径异常;
只在跨特定 leaf/spine 时出现。

3.3 为什么“没有报错”不代表 MTU 无关

很多问题不会直接报一个清晰的 “MTU mismatch”。尤其是通信库封装之后,你可能只看到:

text
带宽低;
尾部高;
某些 pair 慢;
某些消息大小下慢。

所以 MTU 是 baseline 检查项,不是看到报错才查。

3.4 小 case:消息大小敏感

如果:

text
1MiB 消息正常
256MiB 消息慢

可能原因很多:

text
MTU/packetization;
ECMP 大象流;
queue/buffer;
通信库 protocol;
GDRDMA 注册/缓存;
同步尾部。

MTU 只是候选之一,需要结合 perftest、消息大小 sweep、counter 和错误日志判断。


4. DSCP、ECN、PCP、priority、PG、TC、queue

这一节是第 4 周最容易混的部分。

4.1 DSCP

DSCP 在 IP header 里,用于区分服务类别。

text
DSCP = 这包应该属于哪类服务/优先级

它不是带宽保证。交换机可以 trust 它,也可以忽略或改写它。

4.2 ECN

ECN 也在 IP header 里,用于拥塞标记。

text
ECT:这个 flow 支持 ECN
CE:交换机标记“我这里拥塞了”

ECN 标记本身只是信号,后续还要接收端/发送端拥塞控制响应。

4.3 PCP

PCP 在 VLAN tag 里,是二层 priority 标记。

如果网络 trust L2,则 PCP 可能用于映射 priority/queue。

4.4 priority / PG / TC / queue

这些是交换机内部分类和队列概念,厂商命名可能不同。

粗略理解:

text
priority:内部优先级
PG:priority group,PFC 常按 PG/priority 工作
TC:traffic class,调度/队列分类
queue:实际排队资源

4.5 trust mode

交换机收到包后,要决定信谁:

text
trust L2 PCP?
trust L3 DSCP?
按端口默认 priority?
重写 DSCP/PCP?

这就是 trust mode。

4.6 小 case:端点设置 DSCP 但 QoS 没生效

端点发出:

text
DSCP = 32

交换机配置:

text
不 trust DSCP,只 trust PCP
或者入口端口把 DSCP 重写为 0

结果:

text
端点以为自己进了 RoCE 高优先级;
交换机实际把它放进普通队列。

所以光看端点变量不够。


5. 从 MCCL_IB_TC 到交换机 queue:必须闭环

在 Muxi 里,我们关心类似:

text
MCCL_IB_TC=128

但它到底是什么意思,至少要经过这些问题:

text
1. MCCL 是否读取了这个变量?
2. 它把这个值传给 RNIC 的哪个字段?
3. RNIC 生成的 IP header DSCP/ECN 实际是多少?
4. 报文出线后 DSCP/ECN 是否被保留或改写?
5. 交换机入口 trust L3 还是 L2?
6. DSCP/PCP 映射到哪个 priority?
7. priority 映射到哪个 PG/TC/queue?
8. 这个 queue 是否开启 PFC?
9. ECN 阈值是多少?
10. 实验窗口内 pause/CE/CNP/drop/bytes 是否变化?

如果只知道第 1 步或第 2 步,不能写:

text
QoS 已按预期生效。

只能写:

text
端点变量/日志支持某 TC 被设置;交换机侧映射和实际队列行为仍未知。

这正是 Muxi W3/G3 没有通过强结论的原因。


6. 抓包为什么有边界

6.1 tcpdump 能看到什么

如果在合适位置抓包,可能看到:

text
src/dst MAC
src/dst IP
DSCP/ECN bits
UDP ports
packet size
部分 RoCE header

6.2 tcpdump 看不到什么

它可能看不到:

text
交换机内部 queue occupancy;
PFC pause 帧,因为 pause 可能发生在另一个链路;
被交换机改写后的 header,如果抓包点在改写前;
RNIC offload 之后的真实线速细节;
CNP,如果镜像点不对或权限不足;
每个 ECMP uplink 的真实 bytes。

6.3 空 pcap 不能证明“没发生”

如果你没抓到 CNP/CE/PFC,可能是:

text
真的没发生;
抓包点错;
方向错;
命名空间不对;
硬件 offload;
过滤条件错;
事件太短;
交换机改写/消费了某些信号;
权限不足。

所以正确写法是:

text
在当前抓包点和过滤条件下未观察到该信号;不能作为未发生的充分证据。

7. 和 Muxi 现象的关系

Muxi 最终 W3/G3 判断:

text
只证实 MCCL 读取 TC128;
缺 QP/wire/switch/counter 闭环;
不能对交换机拥塞、PFC、ECN、CNP 或 ECMP 机制做强结论。

第 4 周解释了为什么:

text
MCCL 变量
  ≠ wire DSCP/ECN
  ≠ switch priority
  ≠ queue
  ≠ PFC/ECN 触发
  ≠ 发送端降速

中间每一步都需要证据。

对于 Muxi,最小缺口是:

text
xscale/RNIC 如何解释 TC;
实际报文 DSCP/ECN;
H3C trust mode;
DSCP/PCP→priority→PG/TC/queue;
PFC/ECN 阈值;
实验窗口内 counter。

8. 推荐阅读提炼

8.1 NVIDIA / Cumulus RoCE QoS 文档

一句话

这些文档展示 RoCE 网络如何配置 priority、PFC、ECN、DSCP/PCP 映射。

抓哪个问题

text
RoCE 流量如何从端点标记进入交换机 lossless/ECN 队列?

关键吸收

  • QoS 是一条链,不是一个变量。
  • 端点 DSCP/PCP 需要被交换机 trust。
  • priority 需要映射到正确 queue/PG。
  • PFC/ECN 阈值要和 buffer/headroom 协同。

和 Muxi 的关系

它提供检查清单:我们要向 H3C/网络组索取相同类别的信息。

不能照搬

NVIDIA/Cumulus 的 priority 3、DSCP 值、命令行、阈值都不能直接当成 H3C/Muxi 的事实。

8.2 RFC 2474:DSCP

一句话

DSCP 是 IP 层 Differentiated Services 的分类字段。

抓哪个问题

text
DSCP 是“分类标签”,不是“保证带宽”。

小 case

同一个 DSCP,在不同交换机配置下可能:

text
进入高优先级队列;
被改写为 0;
被忽略;
映射到错误 priority。

8.3 RFC 3168:ECN

一句话

ECN 允许网络在不丢包的情况下标记拥塞。

抓哪个问题

text
CE 标记只是拥塞信号,完整闭环还需要端点响应。

和 RoCE 的关系

RoCE/DCQCN 里,CE/CNP/发送端 rate control 共同构成拥塞控制链。只看到 CE 或只看到 CNP 都不一定足够解释最终带宽。

8.4 沐曦 C500 MCCL 编程指南

一句话

这是确认 MCCL 环境变量语义的真相源之一。

抓哪个问题

text
MCCL_IB_TC、MCCL_IB_GID_INDEX、MCCL_ENABLE_VSWITCH 在 Muxi 实现中具体是什么意思?

不能照搬

即使文档说明变量语义,也还需要实际日志和抓包/交换机配置确认是否生效。


9. 常见误判

  • MCCL_IB_TC=128 就等于交换机按预期 priority 处理。
  • DSCP 存在就说明 QoS 生效。
  • tcpdump 没看到 CNP,就说明没有拥塞控制。
  • GID index 能建连,就说明一定走对数据面。
  • MTU 没报错,就说明 MTU 无关。
  • 抓包点看到 ECN=0,就说明整个路径没有 ECN。
  • PFC/ECN 是网络侧机制,所以端点不用看。

10. 本周任务设计

10.1 任务 A:画 QoS 映射链

画出:

text
MCCL_IB_TC → RNIC field → DSCP/ECN/PCP → trust mode → priority → PG/TC/queue → PFC/ECN counter

然后标注每一段:

text
已知 / 未知 / 需要谁提供 / 如何验证

10.2 任务 B:解释 GID index

回答:

text
GID index 是什么?
为什么它是实验变量?
GID index 错可能有哪些表现?

10.3 任务 C:MTU 现象辨析

给定:

text
小消息正常,大消息慢

列出至少 6 个可能原因,并说明 MTU 如何被验证或排除。

10.4 任务 D:空 pcap 辨析

写一段话解释:

text
为什么没有抓到 CNP/PFC/CE,不能证明没有 CNP/PFC/CE?

11. 和 agent 讨论的问题模板

11.1 QoS 链路闭环

text
请帮我画出从 MCCL_IB_TC 到交换机 queue 的映射链。
对每一段标注:已确认、未知、需要谁提供、如何验证。
不要把端点变量直接等同于交换机 QoS 生效。

11.2 抓包解释

text
我有一段抓包没有看到 CE/CNP/PFC。
请列出为什么这不能作为“没有发生”的充分证据,并给出更强的观测方式。

11.3 网络组请求

text
请生成一份 H3C/网络组需要提供的 QoS ground truth 清单。
每项说明它用于验证 QoS 链路中的哪一段。

12. 本周最小掌握清单

  1. RoCEv2 跑在 IP/UDP 上:所以会受 ECMP、DSCP/ECN、MTU 影响。
  2. GID index 是关键实验变量:不能默认正确。
  3. TC 不是 queue:端点变量要经过 wire header 和交换机映射。
  4. DSCP 是分类标签:不是带宽保证。
  5. ECN 是拥塞信号:不是完整拥塞控制。
  6. 抓包有观测边界:空 pcap 不是反证。
  7. QoS 必须闭环:端点、wire、交换机、counter 缺一不可。

13. 本周结束时你应该能解释的一段话

如果有人问:

“MCCL 已经设置了 TC128,那是不是 RoCE QoS 就没问题了?”

你应该能回答:

text
不能这么说。MCCL 设置 TC 只说明端点尝试给 RNIC 传递某个 traffic class。要证明 QoS 生效,还要确认实际 wire 上的 DSCP/ECN/PCP 是什么,交换机入口 trust 哪个字段,如何映射到 priority/PG/TC/queue,该 queue 的 PFC/ECN 阈值是什么,以及实验窗口内 pause、CE、CNP、drop、bytes、queue occupancy counter 如何变化。缺少这些,只能说端点侧设置存在,不能说交换机按预期处理,更不能把 PFC/ECN 写成已证实根因。

14. 进阶 case:MCCL_IB_TC=128 到底可能代表什么

假设你看到实验环境里设置了:

text
MCCL_IB_TC=128

很多人会直接说:

text
RoCE 流量已经走高优先级了。

这句话中间跳过了太多环节。

14.1 第一步:MCCL 是否真的读取了变量

需要日志或源码/文档确认:

text
MCCL 启动时读取 MCCL_IB_TC;
实际打印 TC=128;
没有被其他变量覆盖;
每个 rank 都一致;

如果只有 shell 环境变量,不代表通信库实际使用。

14.2 第二步:TC=128 如何映射到 IP header

在 IPv4/IPv6 里,traffic class / TOS 字段包含 DSCP 和 ECN bits。

你要确认:

text
TC=128 的二进制如何拆?
高 6 bit 是否作为 DSCP?
低 2 bit 是否作为 ECN?
RNIC 是否按这个语义生成 packet?

不同实现可能对变量命名和 bit 解释不同,所以不能凭名字猜。

14.3 第三步:wire 上实际是什么

即使 MCCL 设置了 TC,仍要看真实报文:

text
IP DSCP = ?
IP ECN = ?
VLAN PCP = ?
UDP ports = ?

这需要合适抓包点,且要考虑 offload 和镜像位置。

14.4 第四步:交换机 trust 什么

交换机入口可能配置:

text
trust dscp
trust pcp
untrusted,使用端口默认 priority
rewrite dscp

如果交换机不 trust DSCP,那么 wire 上 DSCP 正确也可能没用。

14.5 第五步:映射到哪个 queue

还要确认:

text
DSCP/PCP → internal priority
priority → PG
PG → queue / TC
queue → scheduler
queue → PFC/ECN threshold

只有到这里,才能说 RoCE 流量进入了某个交换机队列。

14.6 第六步:counter 是否验证行为

最后要看实验窗口内:

text
该 queue bytes 是否增加;
queue occupancy 是否上升;
PFC pause 是否增加;
ECN CE 是否增加;
CNP 是否增加;
drop/retry 是否增加;

没有 counter,就算配置看起来对,也不能证明运行时发生了某个拥塞机制。


15. 进阶 case:GID index 错误的三种层次

15.1 完全不能连

如果 GID 指向不可达地址或 RoCE 版本不匹配,可能直接建连失败。

表现:

text
init 失败;
QP 无法 RTR/RTS;
timeout;

15.2 能连但走错平面

更隐蔽的是:能连,但不是你想测的数据面。

例如:

text
本来想走 xscale RoCE 数据面;
结果走了控制面或另一个 netns/interface;

表现可能是:

text
带宽低;
延迟高;
QoS 不对;
和预期 HCA counter 对不上;

15.3 能连且带宽还行,但实验不可比

如果两次实验 GID index 不同:

text
实验 A: GID index 5
实验 B: GID index 3

即使都能跑,路径也可能不同。这样比较 channel/rail/QoS 就不干净。

15.4 对 Muxi 的要求

每次 run manifest 至少记录:

text
HCA list;
GID index;
interface IP;
route;
MCCL env;
实际日志里通信库选择的 HCA/GID;

16. 进阶 case:MTU 问题为什么很像“网络偶发慢”

16.1 MTU 错误不总是立刻失败

在某些路径或实现里,MTU 不一致可能不是直接报错,而是表现为:

text
大消息吞吐差;
某些 pair 慢;
错误计数增加;
重传增加;
只在跨特定路径时出现;

16.2 如何设计 MTU 相关排查

可以做:

text
固定端点;
固定 rail;
固定 QP;
消息大小 sweep;
记录错误/retry/drop;
对比不同 MTU 设置;

但注意安全边界:不要在生产 fabric 上盲目改交换机 MTU。优先只读查询和小规模验证。

16.3 MTU 与 collective 的关系

AllReduce 大消息会产生大量 packet。如果 MTU/packetization 不理想,可能导致:

text
packet 数增加;
header overhead 增加;
ECMP 大象流持续时间增加;
queue 压力增加;

但这仍只是候选,不是单独证明。


17. 进阶辨析:DSCP、priority、queue、PFC 是四个层次

17.1 DSCP 是 packet 标记

它在 IP header 里:

text
这个 packet 声称自己属于某类服务。

17.2 priority 是交换机内部分类

交换机根据 trust 和映射,把 packet 放进内部 priority。

17.3 queue 是实际排队资源

多个 priority 可能映射到不同 queue,也可能共享某些资源。

17.4 PFC 是某个 priority/PG 上的暂停机制

PFC 是否开启、阈值多少、pause 作用在哪个 priority,都要查配置。

17.5 常见错误链

错误说法:

text
DSCP 设置了,所以 PFC 生效。

正确链路:

text
DSCP 设置
  → switch trust DSCP
  → DSCP 映射 priority
  → priority 映射 PFC-enabled PG
  → queue occupancy 达到 threshold
  → pause counter 增加

少任何一环,都不能下强结论。


18. 进阶 case:空 pcap 的正确写法

假设你抓包没有看到 CNP:

text
tcpdump ... | grep CNP
结果为空

18.1 错误写法

text
没有 CNP,所以没有 ECN/DCQCN。

18.2 正确写法

text
在当前抓包点、方向、过滤条件和权限下,未观察到 CNP。
这削弱了“CNP 在该抓包点可见且大量发生”的假设,
但不能排除其他链路、其他方向、硬件 offload、交换机内部标记或短时间窗口内发生的 CNP/ECN。

18.3 下一步

text
确认抓包点是否在线路路径上;
确认方向;
降低过滤条件;
抓 IP DSCP/ECN;
请求交换机 CE/CNP/pause counter;
请求 RNIC CNP counter;
按实验时间窗对齐;

19. 推荐阅读进一步拆解:如何读 QoS 文档

19.1 读 RoCE QoS 示例,不要照抄数值

很多文档会给示例:

text
priority 3 for RoCE
PFC on priority 3
ECN threshold X/Y
DSCP value Z

你要吸收的是结构,不是数值。

结构是:

text
classify → map → queue → configure PFC/ECN → observe counter

数值必须来自当前 H3C/Muxi 环境。

19.2 读 RFC 2474 时,关注“分类不是保证”

DSCP 只是告诉网络:

text
这个 packet 希望按某类服务处理。

但它不保证:

text
一定高优先级;
一定不丢;
一定不排队;
一定有带宽;

19.3 读 RFC 3168 时,关注“信号不是控制”

ECN CE 是拥塞信号。完整控制还需要:

text
谁看到 CE;
谁生成反馈;
发送端如何降速;
降速参数是什么;

RoCE 里这会接到 CNP/DCQCN。

19.4 读沐曦 MCCL 文档时,关注“变量到字段”

你要找的不是“有没有这个变量”,而是:

text
变量控制哪个对象?
是 QP 属性,还是 packet TC?
是所有 HCA 生效,还是部分路径?
是否能日志打印?
默认值是什么?

20. 本周自测题:带答案方向

20.1 为什么端点设置 TC 不等于 QoS 生效?

答案方向:

text
TC 需要实际体现在 wire DSCP/ECN/PCP,再被交换机 trust 和映射到正确 priority/queue,并在 counter 中体现行为。中间任何一段未知都不能闭环。

20.2 GID index 为什么是实验变量?

答案方向:

text
GID index 决定 RDMA/RoCE 端点地址和可能的数据面路径。不同 GID index 可能走不同 interface、RoCE version 或网络平面。

20.3 为什么空 pcap 不能排除 PFC/ECN/CNP?

答案方向:

text
抓包点、方向、offload、过滤条件、权限和时间窗口都可能导致看不到信号。需要交换机/RNIC counter 对齐。

20.4 DSCP 和 ECN 有什么区别?

答案方向:

text
DSCP 是服务分类字段,ECN 是拥塞标记字段。DSCP 决定可能进入哪个处理类别,ECN 用于拥塞信号。

20.5 MTU 问题为什么可能只在大消息出现?

答案方向:

text
大消息产生更多 packet,更依赖稳定 packetization 和路径能力;MTU/分片/丢包/重传问题在大消息下更容易放大。