参见内核:https://www.kernel.org/doc/documentation/networking/scaling.txt.
当一个硬件设备产生一个输入核心输出事件时,它会向CPU发送一个信号,这是一个硬中断。收到硬中断后,CPU会停止当前工作,处理优先级最高的硬件中断事件。
2.2软中断(SoftIRQ)
软中断在机制上类似于硬中断,只是优先级略低。在网卡传输数据的过程中,典型的过程是数据到达网卡,网卡通过DMA将数据复制到网卡驱动指定的内存区域,产生硬中断。然后CPU需要自己处理中断,把网卡的数据复制到内核的指定区域,处理TCP/IP协议栈,然后通知应用层,把数据复制到应用层。在这种情况下,如果一旦硬中断到来,CPU一直忙于处理网卡的请求和服务上层应用,网卡后续数据到达产生的硬中断也会延迟,其他设备和进程无法使用这个CPU资源,导致CPU饥饿。因此,在处理设备硬中断时,整个过程分为两个阶段;第一阶段,CPU只使用ISR简单快速的响应硬中断生成软中断,然后CPU继续后续的调度处理,网卡继续收发数据;第二阶段,CPU会根据调度器按照优先级对一系列软中断进行排队,将数据包移动到TCP/IP协议栈和后续应用中。
2.3接收队列
网卡驱动会通过DMA将接收到的数据复制到socketbuffer,并通过socketdescriptor进行标记。所有要处理的数据分组的套接字描述符将被存储在接收队列中。如果有多个接收队列,网卡会根据某种算法将数据包匹配到一个接收队列。现在很多网卡都是通过一种叫做RSS (Receiving Side Scaling)的技术(将数据包的处理任务分配给多个CPU),在硬件上支持Rx多队列。
queuestodistributeprocessingmongcpus。然后是应用过滤器的分配包
oflogicalflows。packetsforeachflowaresteeredtoseparatereceivequeue,它inturncableprocessedbysepatecpus。这个机制是
众所周知。
当数据包到达网卡时,它将被放入接收队列;在网卡驱动的初始化阶段,接收队列将被赋予一个IRQ号,一个CPU将被分配来处理这个IRQ。该CPU需要执行该IRQ的ISR,并且通常还负责内核阶段的后续数据包处理。在单核系统中,这是一个很好的工作模式,但是在多核系统中,这种方式在流量很大的情况下无法发挥多核的作用,只能用一个核来处理耗时的TCP/IP协议栈。
所以在目前的网卡中,大部分都支持RSS的功能。启用此功能后,网卡将有多个接收和发送队列,这些队列将处理不同的CPU分配。
RSS提供多核网卡数据传输支持。RSS在硬件/驱动程序级别实现多队列,并使用哈希函数来分隔数据包。这种hash根据源IP、目的IP、源端口和目的端口来选择分组分布,使得同一数据流的分组会被放在同一个队列中进行处理,在一定程度上可以保证数据处理的均衡性。
rpsrequiresakernlcompiledwitheconfig _ RPSkconfigsymbol(onbydefaultforSMP).Evenwhencompiledin,RP
Sremainsdisableduntilexplicitlyconfigured.ThelistofCPUstowhichRPSmayforwardtrafficcanbeconfiguredforeachreceivequeueusingasysfsfileentry:
/sys/class/net/
RPS是和RSS类似的一个技术,区别在于RSS是网的硬件实现而RPS是内核软件实现。RPS帮助单队列网卡将其产生的SoftIRQ分派到多个CPU内核进行处理。在这个方案中,为网卡单队列分配的CPU只处理所有硬件中断,由于硬件中断的快速高效,即使在同一个CPU进行处理,影响也是有限的,而耗时的软中断处理会被分派到不同CPU进行处理,可以有效的避免处理瓶颈。
WhileRPSsteerspacketssolelybasedonhash,andthusgenerallyprovidesgoodloaddistribution,itdoesnottakeintoaccount
applicationlocality.ThisisaccomplishedbyReceiveFlowSteering(RFS).
RFSisonlyavailableifthekconfigsymbolCONFIG_RPSisenabled(onbydefaultforSMP).Thefunctionalityremainsdisableduntilexplicitly
configured.Thenumberofentriesintheglobalflowtableissetthrough:
/proc/sys/net/core/rps_sock_flow_entries
Thenumberofentriesintheper-queueflowtablearesetthrough:
/sys/class/net/
/queues/rx- /rps_flow_cnt
在使用RPS接收数据包之后,会在指定的CPU进行软中断处理,之后就会在用户态进行处理;如果用户态处理的CPU不在软中断处理的CPU,则会造成CPUcachemiss,造成很大的性能影响。RFS能够保证处理软中断和处理应用程序是同一个CPU,这样会保证localcachehit,提升处理效率。RFS需要和RPS一起配合使用。
TransmitPacketSteeringisamechanismforintelligentlyselectingwhichtransmitqueuetousewhentransmittingapacketonamulti-queue
device.
XPSisonlyavailableifthekconfigsymbolCONFIG_XPSisenabled(onbydefaultforSMP).Thefunctionalityremainsdisableduntilexplicitly
configured.ToenableXPS,thebitmapofCPUs/receive-queuesthatmayuseatransmitqueueisconfiguredusingthesysfsfileentry:
ForselectionbasedonCPUsmap:
/sys/class/net/
/queues/tx- /xps_cpus Forselectionbasedonreceive-queuesmap:
/sys/class/net/
/queues/tx- /xps_rxqs
XPS通过创建CPU到网卡发送队列的对应关系,来保证处理发送软中断请求的CPU和向外发送数据包的CPU是同一个CPU,用来保证发送数据包时候的局部性。
RSS(ReceiveSideScaling):网卡多队列,需要硬件支持。网卡接收到网络数据包之后,要发送一个硬件中断,通知CPU取数据包。默认配置,都是由CPU0去做。
RPS(ReceivePacketSteering):向某CPU发送一个软中断,来接收数据包,并递交给应用程序。
RFS(ReceiveFlowSteering):维护两张hash表,实现将软中断分散到多颗CPU去处理。
XPS(TransmitPacketSteering):创建CPU到网卡发送队列的对应关系,主要是为了避免cpu由RX队列的中断进入到TX队列的中断时发生切换,导致cpucache失效损失性能。
后面会分享更多devops和DBA方面的内容,感兴趣的朋友可以关注下~