1.网卡多队列
网卡升级换代之后,变成了多队列网卡,这个队列指的是供网卡DMA读取的ring buffer,即此时网卡会有多个ring buffer。
当有多个数据包到达网卡时,网卡的微处理器,根据数据包的源端口,目的端口,源ip,目的ip四元组进行hash,相同的四元组总是hash到同一个队列中,不同的四元组hash到不同的队列。
对于每个不同的队列,如果没有进行负载均衡,则由cpu0通过软中断唤醒的NAPI读取网卡队列中的数据包在skb_buffer中的位置和大小,然后pop出这个数据包在队列中的描述符。
当每个不同的队列,设置了负载均衡或进行了网卡亲和性绑定时,不同的CPU则对应了不同的队列,不同的数据包进入到不同的队列时,触发不同的cpu响应中断,不同的cpu各自唤醒自己的NAPI对不同队列进行处理。
(2)RSS、RPS、RFS
RSS:网卡本身支持多队列时,可以直接使用RSS技术,直接由网卡的微处理器进行hash进行多队列处理,
RPS:在网卡驱动中根据数据包的四元组进行hash,此时cpu已经完成硬中断,而数据包也已经到达skb_buffer,而完成硬中断的cpu核此时触发自身的软中断,并调用网卡驱动程序的注册函数,进行数据包四元组的hash计算,完成实际数据包的处理软中断的cpu核分配,也就是说,其实此时还在进行网卡数据包的硬中断的cpu处理核上增加了一次软中断,只是该调度核上面不再进行数据包协议栈的处理,涉及内核协议栈处理的过程的软中断交给了调度核。
RFS:虽然完成了数据包的软中断处理的核分配,但是如果,用户态的应用程序与内核协议栈处理过程的软中断使用的cpu核不一致,又会造成cpu cache的命中率降低,大大浪费了cpu的性能,因此需要给用户态的应用程序和对应flow中的数据包的cpu核处理为同一个,实现的过程就是给该应用程序hash一个id,使用该id去匹配对应的核,匹配的过程就是一个全局的rps_sock_flow_table中有没有关于当前hash值对应的cpu核,如果有,就继续使用该cpu核,如果没有,就使用RPS分配的核,从而保证了应用程序与软中断使用了同一个cpu核。
参考文献:
8.8. Receive Flow Steering (RFS) Red Hat Enterprise Linux 6 | Red Hat Customer Portal