当数据包到达时,网卡通过DMA复制数据包并发送中断,Linux内核收集这些数据包并完成中断处理。
随着网卡越来越快,基于中断会因大量传入数据包而导致 IRQ 瘫痪,消耗大部分 CPU 功率。
NAPI(中断+轮训)与现在常见的 1 Gbps 网卡配合使用。
但是,对于10Gbps、20Gbps甚至40Gbps的网卡,NAPI可能还不够Receive Side Scaling(RSS)多个RX / TX队列过程的数据包当接收到数据包时,会对数据包应用过滤器并将数据包分发到RX 队列。
echo 3 > /proc/irq/xxx/smp_affinity
RSS提供硬件队列
Receive Packet Steering 散列是所谓的第 4 层散列(l4 散列),它基于源 IP、源端口、目的 IP 和目的端口,由网卡或__skb_set_sw_hash() 计算。
设置rps在cpu0/1上均衡
echo 3 > /sys/class/net /eth0/queues/rx-0/rps_cpus
从 eth0 中队列 0 接收的数据包进入 CPU 1~3。
驱动程序在 sk_buff 中包装一个数据包后,它将到达netif_rx_internal()或netif_receive_skb_internal(),然后到达 get_rps_cpu可以在 CPU 之间分担数据包处理的负载
Receive Flow Steering(RFS)基于流分发数据包
echo 32768 > /proc/sys/net/core/rps_sock_flow_entries
当调度器将应用程序迁移到新 CPU 时,旧 CPU 队列中剩余的数据包变得未完成,应用程序可能会得到乱序的数据包。
为了解决这个问题,RFS 使用每个队列的rps_dev_flow_table来跟踪未完成的数据包。
ARFS加速接收流量转向SO_REUSEPORT支持多个进程或者线程绑定到同一端口
/proc/interrupt查看硬中断次数
/proc/softirq查看软中断次数
RPS由单一CPU核响应硬件中断,将大量网络接收包,通过多核间中断方式分发给其他空闲核