以太网 QoS
服务质量 (QoS) 是一种机制,用于为网络流(套接字、rdma_cm
连接)分配优先级,并管理其保证、限制以及相对于其他流的优先级。这是通过一个 2/3 阶段的过程,将用户的优先级映射到硬件 TC(流量类别)来实现的。TC 被分配 QoS 属性,不同的流据此运行。
将流量映射到 TC 包含多个用户可控制的操作,其中一些由应用程序本身控制,另一些由系统/网络管理员控制。
以下是将流量映射到流量类别的一般流程
应用程序设置所需的服务类型 (ToS)。
ToS 被转换为套接字优先级 (
sk_prio
)。sk_prio
由系统管理员映射到用户优先级 (UP)(某些应用程序直接设置sk_prio
)。UP 由网络/系统管理员映射到 TC。
TC 包含实际的 QoS 参数
QoS 可以应用于以下类型的流量。但是,它们之间的一般 QoS 流程可能有所不同
普通以太网 – 应用程序使用常规 inet 套接字,流量通过内核以太网驱动程序
RoCE – 应用程序使用 RDMA API 通过队列对 (QP) 进行传输
原始以太网 QP – 应用程序使用 VERBs API 通过原始以太网 QP 进行传输
应用程序使用常规 inet 套接字,流量通过内核以太网驱动程序。以下是普通以太网 QoS 映射流程
应用程序使用 setsockopt (IP_TOS, value) 设置套接字的 ToS。
ToS 使用固定转换转换为 sk_prio
TOS
0
<=> sk_prio0
TOS8
<=> sk_prio2
TOS24
<=> sk_prio4
TOS16
<=> sk_prio6
在以下情况下,套接字优先级映射到 UP
如果底层设备是 VLAN 设备,则使用由 vconfig 命令控制的 egress_map。这是每个 VLAN 的映射。
如果底层设备不是 VLAN 设备,则在驱动程序中完成映射。
UP 映射到 TC,由 mlnx_qos 工具或 lldpad 守护程序(如果使用 DCBX)配置。
套接字应用程序可以使用 setsockopt (SK_PRIO, value) 直接设置套接字的 sk_prio
。在这种情况下,不需要 ToS 到 sk_prio
的固定映射。这允许应用程序和管理员利用超过通过 ToS 可能实现的 4 个值。
在 VLAN 接口的情况下,根据上述映射获得的 UP 也用于流量的 VLAN 标记中。
应用程序使用 RDMA-CM API 创建和使用 QP。以下是 RoCE QoS 映射流程
应用程序使用 rdma_set_option 选项 (RDMA_OPTION_ID_TOS, value) 设置 QP 的 ToS。
ToS 使用固定转换转换为套接字优先级 (sk_prio)
TOS
0
<=> sk_prio0
TOS8
<=> sk_prio2
TOS24
<=> sk_prio4
TOS16
<=> sk_prio6
套接字优先级使用 tc 命令映射到用户优先级 (UP)。
在 VLAN 设备的情况下,父级真实设备用于此映射目的
如果底层设备是 VLAN 设备,并且父级真实设备未用于映射,则使用 VLAN 设备的 egress_map
4. UP 映射到 TC,由 mlnx_qos 工具或 lldpad 守护程序(如果使用 DCBX)配置。
对于 RoCE,出于 QoS 映射的目的,只能有 4 个预定义的 ToS 值。
对于不支持 set_egress_map 的 RoCE 旧内核,请使用 tc_wrap 脚本在 sk_prio 和 UP 之间进行映射。使用带有 -u 选项的 tc_wrap。例如
tc_wrap -i <ethX> -u <skprio2up mapping>
可以分配给 TC 的不同 QoS 属性有
严格优先级
当将 TC 的传输算法设置为“strict”时,此 TC 相对于其之前出现的其他 TC 严格优先级(由 TC 编号确定:TC 7 最高优先级,TC 0 最低优先级)具有绝对(严格)优先级。它还相对于非严格 TC (ETS) 具有绝对优先级。
此属性需要谨慎使用,因为它可能很容易导致其他 TC 资源匮乏。
始终优先考虑传输具有较高严格优先级的 TC。只有当最高严格优先级的 TC 没有更多内容要传输时,才会考虑下一个最高优先级的 TC。
非严格优先级 TC 将最后被考虑传输。
此属性对于需要立即获得服务的低延迟、低带宽流量非常有用,但其量不大,不会导致系统中其他发送器资源匮乏。
增强传输选择 (ETS)
增强传输选择标准 (ETS) 利用特定流量类别 (TC) 的提供负载小于其最小分配带宽的时间段,从而允许将差值提供给其他流量类别。
在服务完严格优先级 TC 后,线路上的剩余带宽 (BW) 可以根据最小保证策略在其他 TC 之间进行分配。
例如,如果 TC0 设置为 80% 保证,TC1 设置为 20%(TC 总和必须为 100),则在服务完所有严格优先级 TC 后,剩余的 BW 将根据此比率进行分配。
由于这是最小保证,因此没有最大强制执行。这意味着,在同一示例中,如果 TC1 没有使用其 20% 的份额,则剩余部分将由 TC0 使用。
ETS 使用 mlnx_qos 工具 (mlnx_qos) 进行配置,该工具允许您
为每个 TC 分配传输算法(严格或 ETS)
为 ETS TC 设置最小 BW 保证
用法
mlnx_qos -i \[options\]
速率限制
速率限制定义了 TC 允许的最大带宽。请注意,请求值 10% 的偏差被认为是可接受的。
信任状态
信任状态允许根据数据包字段对发送/接收的数据包进行优先级排序。
默认信任状态为 PCP。以太网数据包根据字段值 (PCP/DSCP) 确定优先级。
有关如何配置信任模式的更多信息,请参阅 NVIDIA 适配器上如何配置信任状态 社区帖子。
应在启用 SR-IOV 之前设置信任状态模式,以便将信任状态传播到 VF。
接收缓冲区
默认情况下,接收缓冲区配置是自动控制的。用户可以使用 mlnx_qos 工具覆盖接收缓冲区大小和接收缓冲区的 xon 和 xoff 阈值。
有关更多信息,请参阅 NVIDIA 适配器上如何调整接收缓冲区 社区帖子。
DCBX 控制模式
DCBX 设置(例如“ETS”和“严格优先级”)可以由固件或软件控制。当 DCBX 由固件控制时,QoS 设置的更改不能由软件完成。DCBX 控制模式使用 mlnx_qos -d os/fw 命令配置。
有关如何配置 DCBX 控制模式的更多信息,请参阅 mlnx_qos 社区帖子。
mlnx_qos
mlnx_qos 是一个集中式工具,用于配置本地主机的 QoS 功能。它直接与驱动程序通信,因此不需要在系统上设置 DCBX 守护程序。
mlnx_qos 工具使系统管理员能够
检查当前的 QoS 映射和配置
该工具还将显示由 TC 和 vconfig set_egress_map 工具配置的映射,以便提供所有 QoS 映射的集中视图。
设置 UP 到 TC 的映射
为每个 TC 分配传输算法(严格或 ETS)
为 ETS TC 设置最小 BW 保证
为 TC 设置速率限制
设置 DCBX 控制模式
设置电缆长度
设置信任状态
对于无限制的速率限制,将速率限制设置为 0。
用法
mlnx_qos -i <interface
> \[options\]
选项
--version | 显示程序版本号并退出 |
-h, --help | 显示此帮助消息并退出 |
-f LIST, --pfc=LIST | 为每个优先级设置优先级流控制。LIST 是 每个优先级的逗号分隔值,从 0 到 7。示例:0,0,0,0,1,1,1,1 启用 TC4-7 上的 PFC |
-p LIST, --prio_tc=LIST | 将 UP 映射到 TC。LIST 是 8 个逗号分隔的 TC 编号。示例:0,0,0,0,1,1,1,1 将 UP 0-3 映射到 TC0,将 UP 4-7 映射到 TC1 |
-s LIST, --tsa=LIST | 每个 TC 的传输算法。LIST 是每个 TC 的逗号分隔的算法名称。可能的算法:strict、ets 和 vendor。示例:vendor,strict,ets,ets,ets,ets,ets,ets 将 TC0 设置为 vendor,TC1 设置为 strict,TC2-7 设置为 ets |
-t LIST, --tcbw=LIST | 为 ETS TC 设置最小保证 %BW。LIST 是每个 TC 的逗号分隔的百分比。设置为未配置为 ETS 算法的 TC 的值将被忽略,但必须存在。示例:如果 TC0,TC2 设置为 ETS,则 10,0,90,0,0,0,0,0 将 TC0 设置为 10%,TC2 设置为 90%。百分比总和必须为 100 |
-r LIST, --ratelimit=LIST | TC 的速率限制(以 Gbps 为单位)。LIST 是每个 TC 的逗号分隔的 Gbps 限制。示例:1,8,8 将 TC0 限制为 1Gbps,TC1,TC2 各限制为 8 Gbps |
-d DCBX, --dcbx=DCBX | 将 dcbx 模式设置为固件控制 (fw) 或操作系统控制 (os)。注意,在操作系统模式下,mlnx_qos 不应与其他 dcbx 工具(例如 lldptool)并行使用 |
--trust=TRUST | 将优先级信任状态设置为 pcp 或 dscp |
--dscp2prio=DSCP2PRIO | 设置/删除 (dscp,prio) 映射。示例“set,30,2”将 dscp 30 映射到优先级 2。“del,30,2”将 dscp 30 映射重置为默认设置优先级 0 |
--cable_len=CABLE_LEN | 为缓冲区的 xoff 和 xon 阈值设置 cable_len |
-i INTF, --interface=INTF | 接口名称 |
-a | 显示所有接口的 TC |
获取当前配置
ofed_scripts/utils/mlnx_qos -i ens1f0
DCBX mode: OS controlled
Priority trust state: dscp
dscp2prio mapping:
prio:0
dscp:07
,06
,05
,04
,03
,02
,01
,00
,
prio:1
dscp:15
,14
,13
,12
,11
,10
,09
,08
,
prio:2
dscp:23
,22
,21
,20
,19
,18
,17
,16
,
prio:3
dscp:31
,30
,29
,28
,27
,26
,25
,24
,
prio:4
dscp:39
,38
,37
,36
,35
,34
,33
,32
,
prio:5
dscp:47
,46
,45
,44
,43
,42
,41
,40
,
prio:6
dscp:55
,54
,53
,52
,51
,50
,49
,48
,
prio:7
dscp:63
,62
,61
,60
,59
,58
,57
,56
,
Cable len: 7
PFC configuration:
priority 0
1
2
3
4
5
6
7
enabled 0
0
0
0
0
0
0
0
tc: 0
ratelimit: unlimited, tsa: vendor
priority: 1
tc: 1
ratelimit: unlimited, tsa: vendor
priority: 0
tc: 2
ratelimit: unlimited, tsa: vendor
priority: 2
tc: 3
ratelimit: unlimited, tsa: vendor
priority: 3
tc: 4
ratelimit: unlimited, tsa: vendor
priority: 4
tc: 5
ratelimit: unlimited, tsa: vendor
priority: 5
tc: 6
ratelimit: unlimited, tsa: vendor
priority: 6
tc: 7
ratelimit: unlimited, tsa: vendor
priority: 7
设置速率限制(tc0 为 3Gb/s,tc1 为 4Gb/s,tc2 为 2Gb/s)
# mlnx_qos -i <interface
> -p 0
,1
,2
-r 3
,4
,2
tc: 0
ratelimit: 3
Gbps, tsa: strict
up: 0
skprio: 0
skprio: 1
skprio: 2
(tos: 8
)
skprio: 3
skprio: 4
(tos: 24
)
skprio: 5
skprio: 6
(tos: 16
)
skprio: 7
skprio: 8
skprio: 9
skprio: 10
skprio: 11
skprio: 12
skprio: 13
skprio: 14
skprio: 15
up: 3
up: 4
up: 5
up: 6
up: 7
tc: 1
ratelimit: 4
Gbps, tsa: strict
up: 1
tc: 2
ratelimit: 2
Gbps, tsa: strict
up: 2
配置 QoS(将 UP 0,7 映射到 tc0,1,2,3 映射到 tc1,4,5,6 映射到 tc2。将 tc0,tc1 设置为 ets,tc2 设置为 strict。将 ets 分配为 tc0 30% 和 tc1 70%)
# mlnx_qos -i <interface
> -s ets,ets,strict -p 0
,1
,1
,1
,2
,2
,2
-t 30
,70
tc: 0
ratelimit: 3
Gbps, tsa: ets, bw: 30
%
up: 0
skprio: 0
skprio: 1
skprio: 2
(tos: 8
)
skprio: 3
skprio: 4
(tos: 24
)
skprio: 5
skprio: 6
(tos: 16
)
skprio: 7
skprio: 8
skprio: 9
skprio: 10
skprio: 11
skprio: 12
skprio: 13
skprio: 14
skprio: 15
up: 7
tc: 1
ratelimit: 4
Gbps, tsa: ets, bw: 70
%
up: 1
up: 2
up: 3
tc: 2
ratelimit: 2
Gbps, tsa: strict
up: 4
up: 5
up: 6
tc 和 tc_wrap.py
tc 工具用于创建 8 个流量类别 (TC)。
该工具将使用 sysfs (/sys/class/net/用法
tc_wrap.py -i <interface
> \[options\]
选项
--version | 显示程序版本号并退出 |
-h, --help | 显示此帮助消息并退出 |
-u SKPRIO_UP, --skprio_up=SKPRIO_UP | 将 sk_prio 映射到 RoCE 的优先级。LIST 是 <=16 个逗号分隔的优先级。元素的索引是 sk_prio |
-i INTF, --interface=INTF | 接口名称 |
tc_wrap.py -i enp139s0
输出
Tarrfic classes are set to 8
UP 0
skprio: 0
(vlan 5
)
UP 1
skprio: 1
(vlan 5
)
UP 2
skprio: 2
(vlan 5
tos: 8
)
UP 3
skprio: 3
(vlan 5
)
UP 4
skprio: 4
(vlan 5
tos: 24
)
UP 5
skprio: 5
(vlan 5
)
UP 6
skprio: 6
(vlan 5
tos: 16
)
UP 7
skprio: 7
(vlan 5
)
其他工具
需要使用 sch_mqprio 模块编译的 tc 工具来支持 kernel v2.6.32 或更高版本。这是 iproute2 包 v2.6.32-19 或更高版本的一部分。否则,可以使用替代的自定义 sysfs 接口。
mlnx_qos 工具(软件包:ofed-scripts)需要 python 版本 2.5 < = X
tc_wrap.py(软件包:ofed-scripts)需要 python 版本 2.5 < = X
ConnectX-4 及以上设备允许每个流进行数据包步调(流量整形)。此功能通过将流映射到专用发送队列并在该发送队列上设置速率限制来实现。
注意以下几点
最多支持 512 个发送队列
支持 16 种不同的速率
速率可以在 1 Mbps 到线速率之间变化,分辨率为 1 Mbps
多个队列可以映射到相同的速率(每个队列独立步调)
可以并行配置每个 CPU 和每个流的速率限制
系统要求
驱动程序 v3.3 或更高版本
Linux 内核 v4.1 或更高版本
ConnectX-4 或 ConnectX-4 Lx 适配器卡,具有官方固件版本
数据包步调配置
此配置是非持久性的,并且在驱动程序重启后不会保留。
固件激活
首先,确保 MFT 服务 (mst) 已启动
# mst start
然后运行
#echo
"MLNX_RAW_TLV_FILE"
> /tmp/mlxconfig_raw.txt #echo “0x00000004
0x0000010c
0x00000000
0x00000001
" >> /tmp/mlxconfig_raw.txt #yes | mlxconfig -d <mst_dev> -f /tmp/mlxconfig_raw.txt set_raw > /dev/null
#reboot /mlxfwreset#echo
"MLNX_RAW_TLV_FILE"
> /tmp/mlxconfig_raw.txt #echo “0x00000004
0x0000010c
0x00000000
0x00000000
" >> /tmp/mlxconfig_raw.txt #yes | mlxconfig -d <mst_dev >-f /tmp/mlxconfig_raw.txt set_raw > /dev/null
#reboot /mlxfwreset驱动程序激活
数据包步调有两种操作模式
每个 CPU 核心的速率限制
当启用 XPS 时,来自 CPU 核心的流量将使用相应的发送队列发送。通过限制该队列上的速率,将限制该 CPU 核心上的传输速率。例如
echo
300
> /sys/class
/net/ens2f1/queues/tx-0
/tx_maxrate在这种情况下,Core 0 (tx-0) 上的速率被限制为 300Mbit/秒。
每个流的速率限制
驱动程序允许使用以下命令打开最多 512 个额外的发送队列
ethtool -L ens2f1 other
1200
在这种情况下,打开了 1200 个额外的队列
创建流映射。
用户可以将特定目标 IP 和/或目标第 4 层端口映射到特定的发送队列。匹配优先级如下
IP + L4 端口
仅 IP
仅 L4 端口
无匹配(流将映射到默认队列)
创建流映射
配置目标 IP。以十六进制表示形式将 IP 地址写入相关的 sysfs 条目。例如,要将 IP 地址 192.168.1.1 (0xc0a80101) 映射到发送队列 310,请运行以下命令
echo
0xc0a80101
> /sys/class
/net/ens2f1/queues/tx-310
/flow_map/dst_ip要将目标 L4 3333 端口(TCP 或 UDP)映射到同一队列,请运行
echo
3333
> /sys/class
/net/ens2f1/queues/tx-310
/flow_map/dst_port从此刻开始,所有发往给定 IP 地址和 L4 端口的流量都将使用发送队列 310 发送。所有其他流量将使用原始发送队列发送。
iii. 使用以下命令限制此流的速率
echo 100
> /sys/class
/net/ens2f1/queues/tx-310
/tx_maxrate
每个队列仅支持单个 IP+端口组合。