1、网卡收发模式
(1)网络发送模式
1)TSO(TCP Segmentation Offload)
是一种利用网卡对TCP数据包分片,减轻CPU负荷的一种技术,有时也被叫做 LSO (Large segment
offload),TSO是针对TCP的,UFO是针对UDP的。如果硬件支持 TSO功能,同时也需要硬件支持的TCP校验计算和分散/聚集 (Scatter Gather) 功能。
2)GSO(Generic Segmentation Offload)
它比TSO更通用,基本思想就是尽可能的推迟数据分片直至发送到网卡驱动之前,此时会检查网卡是否支持分片功能(如TSO、UFO),如果支持直接发
送到网卡,如果不支持就进行分片后再发往网卡。这样大数据包只需走一次协议栈,而不是被分割成几个数据包分别走,这就提高了效率。
(2)网络接收模式
1)LRO(Large Receive Offload)
通过将接收到的多个TCP数据聚合成一个大的数据包,然后传递给网络协议栈处理,以减少上层协议栈处理 开销,提高系统接收TCP数据包的能力。
2)GRO(Generic Receive Offload):
基本思想跟LRO类似,克服了LRO的一些缺点,更通用。后续的驱动都使用GRO的接口,而不是LRO。
3)RSS(Receive Side Scaling)
具备多个RSS队列的网卡,可以将不同的网络流分成不同的队列,再分别将这些队列分配到多个CPU核心上进行处
理,从而将负荷分散,充分利用多核处理器的能力。
RSS需要硬件支持,需要支持MSI-X中断方式的网卡。网卡接收到网络数据包后,要发送一个硬件中断,通知CPU取数据包。默认配置,都是由CPU0去做。
4)RPS(receive packet steering)
向某个CPU发送一个软中断,来接收数据包,并递交给应用程序。
5)RFS(receive flow streering):
维护两种hash表,实现将软中断分散到多颗CPU上去处理。
2、中断请求机制
PCI(外设部件互连标准)支持两种中断,INTx中断请求机制(引脚提交中断请求)和MSI中断请求机制(中断服务器程序)
区别如下:
1)MSI(Message Signaled Interrupt)是PCI2.2提出的新的中断处理形式,即有中断产生时在系统特定内存地址写入中断数据已通知CPU一个中断。该种方式脱离了中断引脚(
PIN)带来的数目限制,并且延迟小、效率高。MSI的扩展MSI-X在3.0里定义,相较MSI,MSI-X支持更多的消息数量(2048)以及独立的消息地址。MSI支持32个消息,一个MSI地址。
2)基于引脚的PCI中断往往被多个设备所共享,内核需要判断并调用相应的中断处理函数,这样效率就比较低。
MSI不存在共享问题。中断共享的时候,中断触发以后,由于Linux并不知道是哪个设备产生的,所以要一一调用对应的ISR(interrupt service routines)来确定。
3)当设备向内存写入数据,然后发起引脚中断时,有可能在CPU收到中断时,数据还未到达内存(在PCI-PCI桥后的设备更有可能如此)。为了保证数据
已达内存,中断处理程序必须轮询产生该中断的设备的一个寄存器,PCI事务保序规则会确保所有数据到达内存后,寄存器才会返回值。使用MSI时,产生
中断的写不能越过数据写,因而避免了这个问题。当中断产生时,驱动可以确信所有数据已经到达内存。
4)对于多功能PCI设备而言,每一个功能最多只有一个中断引脚。设备驱动程序必须查询设备产生的具体事件,势必降低中断处理速度。而一个设备可以
支持最多32个MSI中断,每个中断有其特定功能,譬如,一些一场情况和错误处理有其单独的中断能让驱动程序处理如数据收发中断更有效。
3、网卡模式使用
(1)网卡查看
查看选择支持msi-x中断方式的网卡
#lspci –v
查看支持多队列网卡,如果有MSI-X && Enable+ && TabSize > 1,则该网卡是多队列网卡
#lspci –vvv
ethtool 查看网卡模式
ethtool -k <网卡接口>,ethtool --show-offload <网卡接口>,或者可以看到很多网络接口的offload特性。
#sudo ethtool -k eth0
Offload parameters for eth0:
rx-checksumming: on
tx-checksumming: on
scatter-gather: on
tcp-segmentation-offload: on
udp-fragmentation-offload: off
generic-segmentation-offload: on
generic-receive-offload: on
large-receive-offload: off
(2)开启网卡接收模式
2.6.35 以后的内核版本都支持google的RPS/RFS补丁。这个功能默认关闭需要手工开启.
开启RPS(两颗4 core的CPU)
#echo ff > /sys/class/net/eth0/queues/rx-0/rps_cpus
开启RFS(内存大的机器可以设置大于4096)
#echo 4096 > /sys/class/net/eth0/queues/rx-0/rps_flow_cnt
开启RSS,网卡多队列 4096*N(N网卡队列数# cat /proc/interrupts | grep eth0)
#echo 32768 > /proc/sys/net/core/rps_sock_flow_entries
(3)关闭网卡收发特性
/usr/sbin/ethtool -K eth1 gro off
/usr/sbin/ethtool -K eth1 lro off
/usr/sbin/ethtool -K eth1 tso off