随着数据中心网络技术和带宽不断发展,流控技术在网络中发挥着越来越重要的作用,但一直未曾有过很大变革。直到无损网络的出现,流控技术出现新突破。作为以太网的基本功能之一,流控技术用于可以防止拥塞的情况下出现丢包,还能配合发送端合理的调整发送速率,从整体上保障网络带宽的最高效率。
IEEE 802.3x是全双工以太网数据链路层的流控方法,当客户终端向服务器发出请求后,自身系统或网络产生拥塞时,它会向服务器发出PAUSE帧,以延缓服务器向客户终端的数据传输。
1. 以太网流控概念
1.1 以太网流控引入
流控是以太网的一项基本功能,可以防止在端口拥塞的情况下出现的丢帧,我们先看一个简单的使用场景:
端口A和端口B接收报文,端口C向外转发报文,如果端口A和端口B的收包速率之和大约端口C的带宽,那么部分报文就会缓存在设备内部的报文buffer中。
对于这种情况下,内部buffer满了,就会出现处理不及时,出现丢帧的情况,等将内部buffer报文转发完毕后,再重新发送报文。
对于这种情况下,就引入流控帧,其处理方式如下:
当buffer的占用率达到一定程度时,端口A和端口B就会向外发送PAUSE帧,通知对端暂停发送一段时间。PAUSE帧只能阻止对端发送普通的数据帧,不能阻止发送MAC控制帧。
注意:
以上的描述有个先决条件,那就是端口A和B工作在全双工模式下,并且使能了流控功能。另一方面,我们也一厢情愿地认为对端可以识别PAUSE帧,并可以做出适当的响应。换句话说,对端的端口也要开启流控功能。
IEEE 802.3x标准定义了一个新的方法,在全双工环境中去实现流量控制(PAUSE)。其实现如下:
- 作为一种减少接收包缓冲区溢出的可能性的方法来实现的,这种溢出会导致接收包的丢失
- 允许对网络拥塞级别进行本地控制
- 可以通过向发射站发送接收站中几乎满的接收缓冲区状态的指示来实现
也就是说PAUSE的功能是为了防止瞬时过载导致缓冲区溢出时不必要的帧丢失。实现了一种简单的停-等式流量机制。
1.2 PAUSE帧功能
PAUSE帧位于网络报文协议中的数据链路层,IEEE802.3 将数据链路层分为三层:LLC,MAC控制子层(可选)和MAC介质访问控制子层。
MAC控制子层规定了通用的全双工流量控制结构,其大致作用如下
交换控制电路要防止缓冲区溢出,可以利用MAC控制子层来控制以太网介质访问控制子层的操作。当已用缓冲区容量达到一个预先设定的阈值时,端口向全双工链路对方发出停止发送数据的请求,这个请求通过MAC控制子层产生的控制帧实现。
同样,端口可以接收由其他站点MAC控制子层产生的控制帧,控制帧夹在客户数据帧流中发送,接收方会根据帧的内容将控制帧分离出来,提交到MAC控制子层中的流量控制模块,流量控制模块解析控制帧的内容,提取帧中的控制参数,根据控制参数决定暂停发送的时间。
1.3 PAUSE帧格式
PAUSE帧格式如下:
MAC控制帧(PAUSE帧)是符合IEEE802.3协议的以太网帧,可以通过其唯一的类型域标识符(0x8808)识别。MAC控制帧在网络上的发送和接收与数据帧类似,除了前导码和帧开始符外,长度为以太网帧的最小帧长度(64字节)。
PAUSE帧各个字段的定义如下:
- 目的地址:协议规定PAUSE的目的地址为保留的组播地址0x01-80-C2-00-00-01。
- 源地址:发送PAUSE帧端口的48位MAC地址。
- 类型:MAC控制帧(PAUSE帧)是符合IEEE802.3协议的以太网帧,可以通过其唯一的类型域标识(0x8808)识别。
- 操作码:恒为0x0001。其实,PAUSE帧是MAC控制帧的一种,其他类型的MAC控制帧使用不同的opcode值,此处不做详细说明。后面会谈到和PAUSE类似的PFC帧,PFC帧中该域的取值是0x0101。
- 操作参数:2字节的暂停时间参数。它是PAUSE发送方请求对方停止发送数据帧的时间长度,通常0xFFFF时间度量单位是以当前传输速率传输512位数据所用的时间,接收方实际暂停的时间为操作参数字段内容与以当前传输速率传输512位数据所用时间的乘积。
- 校验序列(FCS):4个字节的循环冗余校验序列(CRC)字段。CRC 是一种数学算法,MAC发送侧(MAC_TX)创建每个帧时都将运行它。MAC接收侧(MAC_RX)接收到帧时以preamble, SFD, DA, SA, Length/Type, DATA and Pading,作为输入数据进行 CRC 计算,计算结果与接收帧的FCS字段比较,结果相同表示帧有效,结果不同接收方认为发生了错误,进而将帧丢弃。
使用wireshark软件分析PAUSE帧:
1.4 PAUSE帧处理流程
如图所示,为两个网络交互设备MAC0和MAC1,都包含了发送侧TX和接收侧RX
其流控处理流程如下所示
- (1) MAC1发送数据经过1发送数据给MAC0端的RX模块,经过接收后数据进入到MAC0的接收数据缓冲区
- (2) 正常情况下,MAC0接收到的数据,经过缓冲区后,马上就转发出去,转发的速率由网络的速率决定。当MAC1发送速率过大,大约MAC0的发送速率的时候,MAC0内部控制器由于无法及时处理输入数据,需要对端MAC减小数据输入,从而将fc_rdy拉高
- (3) MAC侧的tx端发现流控信号fc_rdy拉高,则需要产生pause帧发送给MAC1接收端。只要fc_rdy拉高,MAC0发送端tx每隔一段时间发送一个pause帧,间隔时间由配置寄存器控制,间隔时长计算由计数器counting计算。只要fc_rdy为高期间,mac0 TX侧每间隔一段时间发送一个Pause帧,其他时间按需发送数据等其他报文。Pause帧的发送不能打断正在传输的数据帧。
- (4) MAC1端RX存在一个模块可以识别帧类型,RX端接收到pause帧报文并完成识别,提取pause帧内包括的暂停时间,控制发送端MAC1在暂停时间内,停止发送数据
- (5) MAC1端在暂停时间内,停止发送数据报文。MAC0 TX侧可能会发起多个Pause帧。一旦MAC0端处理完之前的数据后将fc_rdy拉低,则进入第7步。
- (6) 第8步分为两种情况
- fc_rdy拉低,并且counting在计数没有到一个间隔周期,此时发送pause帧,但是帧内暂停时间为0. Mac1接受到pause帧后,控制tx控制立即开始发送数据。
- fc_rdy拉低的同时,counting正好计数到一个间隔周期,此时不发送pause帧。等到上一个pause帧的暂停时间到达后,mac1发送侧tx继续发送数据。
协议约束
**pause的产生发送过程不能中断一个完整的数据报文。**即在第4步中,fc_rdy拉高后,首先mac0 tx侧需要判断当前是否正常数据报文在传输。如果有,则需要在当前数据报文传输完成后才能发送pause帧。也就是说在发送过程中,只能在完整数据报文的间隙插入pause帧。
**新的pause报文暂停时间会覆盖上一个暂停时间。**对mac1来说,当mac1接收到新的pause帧后,暂停时间以最新时间为准。
2. 流控功能分析
2.1 硬件流控支持
在802.3标准文档中,有相关的描述,关于PAUSE主要有PAUSE和ASM_DIR两个标志,分别对应于PS1和PS2。如下图所示:
下面是intel的一款集成MAC和PHY芯片手册的截图
在自协商的信息中,有两个流控的比特位,即PAUSE和ASM_DIR,分别表示Symmetric PAUSE和Asymmetric PAUSE.
- Symmetric PAUSE表示既可以发送又可以接收PAUSE帧
- Asymmetric PAUSE表示只能发送或只能接收PAUSE帧
从描述上看到,PAUSE和ASM_DIR的不同取值,将影响PAUSE的表现。在这里,当PAUSE和ASM_DIR分别取0和1时,表示从本地设备到对端的异步暂停,亦即“Transmit-only”。
流控是必须本地和对端都支持才行,否则只有一则流控开启,则不生效。
假如两端都开启了“PAUSE”功能,则都支持流控发送和接收。
2.2 流控方式
按照ITU-T802.3x协议,流控有两种方式:XON/XFF和耗尽型。
- XON/XOFF机制:利用PAUSE帧唤醒功能进行工作的机制。当一方的接收FIFO达到高水线的时候,向对端发送PAUSE帧(以太网目前定义的唯一一种控制帧)。
PAUSE帧中带一个时间参数,表示收到PAUSE帧的一方要停多长时间:
- 如果时间参数不为0,则停止发送数据报文
- 时间参数等于0,表示收到PAUSE帧的一方可以马上发送(唤醒功能)
- 耗尽型流控:接收到流控帧之后,如果流控时间为0,则取消流控,允许发送数据帧,否则,按照流控时间禁止数据报文发送,流控时间结束后,开始发送数据报文,而不必等待流控时间为0的流控帧。
2.3 软件流控支持
以82583V网卡为例,在《82583v-gbe-controller-datasheet.pdf》数据手册上有如下流控寄存器描述:
- Flow Control Address Low - FCAL (0x0028; RO)
流控低地址:流量控制数据包由802.3X定义为一个唯一的组播地址,或者一个带有指示暂停的EtherType字段的站地址。完整的流控制组播地址为:0x01_80_C2_00_00_01; - Flow Control Address High - FCAH (0x002C; RO)
流控高地址:该寄存器包含48位流控制以太网地址的上位。这个寄存器只有下面的16位有意义。 - Flow Control Type - FCT (0x0030; R/W)
以太网帧类型(0x8808代表PAUSE帧):此寄存器包含硬件匹配的类型字段,用于识别流控制包。只有寄存器的后16位才有意义。 - Flow Control Transmit Timer Value - FCTTV (0x0170; R/W)
流控暂停时间参数:TTV字段中的16位值被插入到传输帧中(无论是XOFF帧还是其他任何暂停帧值)。它以64字节的插槽时间为单位计数。如果软件需要发送一个XON帧,它必须在启动PAUSE帧之前将TTV设置为0x0。
- Flow Control Receive Threshold Low - FCRTL (0x2160; R/W)
流控低水位阀值:此寄存器包含用于确定何时发送XON包的接收阈值。完整的寄存器以字节为单位反映阈值。较低的四位必须被编程为0x0(16字节粒度)。软件必须设置XONE来支持传输XON帧。每次硬件通过接收高阈值(变得更满),然后通过接收低阈值并启用XONE (1b),硬件传输一个XON帧。当XONE被设置时,RTL字段应该被编程为至少0x3(至少48字节)。流量控制接收/传输是通过自动协商过程协商的功能。
- Flow Control Receive Threshold High - FCRTH(0x2168; R/W)
流控高水位阀值:此寄存器包含用于确定何时发送XOFF包的接收阈值。完整的寄存器以字节为单位反映阈值。这个值必须小于分配给接收包缓冲区的最大字节数(RXPBSIZE.RXPbsize),并且较低的四位必须被编程为0x0(16字节粒度)。RTH的值也应该大于FCRTL0.RTL(流控低水位阀值)。每当接收FIFO达到RTH所指示的满度时,如果启用了流控制帧的传输,硬件就会传输一个暂停帧。流量控制接收/传输是通过自动协商过程协商的功能。 - Flow Control Refresh Threshold Value - FCRTV (0x2460; R/W)
流控刷新阀值:此寄存器指示启用传输流控制时流控制计数器的阈值。当计数器达到这个值时,暂停状态的条件仍然有效(缓冲区满度高于低阈值),将向链接伙伴发送暂停(XOFF)帧。如果该字段包含零值,则禁用流控制刷新。
在使用ethtool工具查看网卡信息中,有如下字段可以查看当前流控功能:
localhost-64 ~ # ethtool eth0
Settings for eth0:
Supported ports: [ TP ]
Supported link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Full
Supported pause frame use: No
Supports auto-negotiation: Yes
Advertised link modes: 100baseT/Full
Advertised pause frame use: No
Advertised auto-negotiation: Yes
Speed: 100Mb/s
Duplex: Full
Port: Twisted Pair
PHYAD: 1
Transceiver: internal
Auto-negotiation: on
MDI-X: off (auto)
Supports Wake-on: pumbg
Wake-on: g
Current message level: 0x00000007 (7)
drv probe link
Link detected: yes
查看/设置本地设备流控状态
localhost-64 ~ # ethtool -a eth0
Pause parameters for eth0:
Autonegotiate: on
RX: on
TX: on
通过"ethtool -A"命令设置流控
localhost-64 ~ # ethtool -A eth0 autoneg off /* 关闭自协商 */
localhost-64 ~ # ethtool -A eth0 rx off /* 关闭流控接收 */
localhost-64 ~ # ethtool -A eth0 tx off /* 关闭流控发送 */
通过“ethtool -d”命令查看当前网卡寄存器。
localhost-64 ~ # ethtool -d eth0 | grep FC
0x00028: FCAL (Flow control address low) 0x00C28001
0x0002C: FCAH (Flow control address high) 0x00000100
0x00170: FCTTV (Flow control tx timer value) 0x0000FFFF
0x02160: FCRTL (Flow control rx threshold low) 0x80007A50
0x02168: FCRTH (Flow control rx threshold high) 0x00007A60
0x02460: FCRTV (Flow control refresh threshold) 0x00000000
- Flow Control Address Low - FCAL (0x0028; RO)
读取到的寄存器值为:0x00C28001
流控低地址。完整的流控制组播地址为:0x01_80_C2_00_00_01。 - Flow Control Address High - FCAH (0x002C; RO)
读取到的寄存器值为:0x00000100
流控高地址。低16位有效,完整的流控制组播地址为:0x01_80_C2_00_00_01。 - Flow Control Type - FCT (0x0030; R/W)
读到的寄存器值为:0x00008808
以太网帧类型。流控帧的Type类型为0x8808。 - Flow Control Transmit Timer Value - FCTTV (0x0170; R/W)
读到的寄存器值为:0x0000FFFF
流控暂停时间参数。当前流控时间参数65535,时间度量单位是以当前传输速率传输512位数据所用的时间。流控暂停时间为:65535*传输512位数据所用的时间。 - Flow Control Receive Threshold Low - FCRTL(0x2160; R/W)
读到的寄存值为:0x80007A50
流控低水位阀值。第31位为XON使能位,开启。第416位表示当前的流控低阀值,第03位必须被编程为0x0(16字节粒度)。即当前的低水位阀值为31312字节。
具体的需要结合内核源码和ethtool一起分析,整个配置和获取的流程,以后再学习。
3. 总结
本章主要是学习了流控的基本原理和软硬件上流控处理的方式,主要参考文档以太网流量控制