RSS (Receive-side scaling)是一种在智能网卡中广泛使用的算法,它可以在高速网络中同时利用多个CPU内核来处理数据包,在处理接收报文时提供负载均衡,从而避免多个CPU核访问同一个RX队列,消除锁争用,从而允许对接收到的数据包进行可伸缩的处理。
该技术需要通过硬件网卡对接收到的报文进行解析,获取IP地址、协议和端口等五元组信息,通过配置的HASH函数根据五元组信息(或二、三或四元组)计算出HASH值;最后取HASH值的最低有效位(LSB)用于索引间接寻址表RETA(Redirection Table),根据RETA中存储的值将数据报文分配到不同的CPU接收处理。
目前在实现RSS功能时使用的HASH函数通常为Toeplitz hash函数。Toeplitz hash是一种使用Toeplitz矩阵计算Hash值的方法,Toeplitz矩阵的特征是矩阵中每条自左上至右下的斜线上的元素相同。Toeplitz矩阵完全由其第1行和第1列的2n-1个元素确定,除第一行第一列外,其他每个元素都与左上角的元素相同,如下图所示。
微软提出了利用Toeplitz hash进行RSS计算的具体方法。算法1显示了RSS哈希函数的代码。INPUT是报文的5元组信息,随机密钥(RSK)是40字节(320位);微软也给出了该RSK的具体值,如下图所示。
但在这种RSS计算过程中发现,对于相同连接的双向数据报文经过哈希后得到的 Hash 值是不同的,Hash值的不同会出现2个方向的数据报文分配到不同的接收队列,通过不同的CPU进行处理。让两个CPU核心在同一个连接中处理数据包需要在不同的线程/进程之间共享数据结构,这通常需要用锁来保护,这破坏了RSS的原始好处,也会加重CPU的负载。
随后为了解决这种问题,对称RSS被提出并在智能网卡中广泛使用;在网络应用中,如果同一个连接的双向报文在开启RSS之后被分发到同一个CPU上处理,这种RSS就称为对称RSS。对于需要为连接保存一些信息的网络应用来说,对称RSS对性能提升有很大帮助。例如:{sip: 1.1.1.1, dip: 2.2.2.2, sport: 123, dport: 456}和{sip: 2.2.2.2, dip: 1.1.1.1, sport: 456, dport: 123}经过对称RSS会被分发到相同的接收队列,由同一个CPU进行处理。
实现对称RSS,主要是改变了算法中RSK矩阵的值,如下图所示。
而在FPGA硬件智能网卡RSS功能实现中,有两个需要考虑1)五元组信息如何兼容IPV4和IPV6;2)FPGA RTL实现RSS中,多次的异或操作会造成时序变差的问题。
为了解决这两个问题,我们提出了以下解决方案:
(1) IPV4和IPV6五元组的兼容问题:IPV4的五元组共136位(协议8bit,sip 32bit,dip 32bit,sport 32bit,dport 32bit),而IPV6的五元组共296位(协议8bit,sip 128bit,dip 128bit,sport 32bit,dport 32bit),超过了目前对称RSS算法中支持的最大数据288bit;因此为了让IPV4和IPV6均兼容,我们需要将RSK矩阵进行扩充,变成如下图所示,此时可支持的最大数据位为304bit。
(2) 为了解决多次异或的时序差问题,对RSK矩阵进行分析发现,RSK矩阵是一个16列重复的矩阵,如下图所示;图中根据红色箭头方向可以将RSK矩阵变换成 Toeplitz矩阵(该图只画出了矩阵的前32例),通过分析矩阵可以发现,Toeplitz矩阵每16例就会重复,因此可以根据该特性在FPGA RTL实现中可以对RSK矩阵进行拆分。
具体实现方案如下:RSK矩阵可以变化为key = 47'h36ad36ad36ad,具体的RTL代码为
将五元组共296位的数据拆分成16bit为一组进行异或运算,从而大大解决时序差的问题。