RPS
什么是RPS
全称receive packet steering,由Google的Tom Herbert编写,而linux从2.6.35开始引入;
此功能可解决网络软中断的负载均衡,即单个网卡的软中断分散到多个CPU处理,避免单个CPU负载过大导致性能瓶颈;
该功能主要针对单队列网卡多CPU环境,如网卡支持多队列则可使用SMP irq affinity直接绑定硬中断,软中断默认同硬中断运行在同一个CPU;
一般如果开启了SMP irq affinity,就不必使用RPS,但须视具体情况而定(两者可并存);
有必要先搞清楚网卡/CPU如何处理网络中断的:
如下图,可分为4个阶段
1 硬件接收
网卡通过线路接收到帧,将其存储至buffer queue,高级网卡可以有多个queue
2 硬中断
网卡向CPU发送中断通知新帧的到来,并为下一步的软中断做准备
3 软中断
此阶段内核将数据帧从网卡buffer queue取出放入网络栈中处理,此过程网卡与CPU相互协同工作,直到网卡buffer溢出或达到dev_weight(一次软中断处理的帧数)
4 应用接收
应用程序通过POSIX调用(read/recv/recvfrom)接收帧数据并将其从socket移出
而RPS优化了第3个阶段,由网卡根据数据包的IP/port信息计算一个hash值,然将其映射到一个CPU id,这样既分散到多个CPU又确保同一数据源的包由同一CPU处理;
如何使用
可通过配置文件为网卡绑定到特定CPU,/sys/class/net//queues/rx-目录,其中n代表该网卡的多个队列,如果不支持多队列就设置第一个队列rx-0
$ pwd
/sys/class/net/eth0/queues/rx-0
$ ls
rpscpus rps_flow_cnt
$ more rps_cpus
00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000
—设置CPU掩码,类似于SMP IRQ affinity
可通过/proc/softirqs查看系统软中断信息
CPU0 CPU1 CPU2 CPU3
HI: 0 0 0 0
TIMER: 27166 27120 27097 27034
NET_TX: 0 0 0 17
NET_RX: 42 0 0 39
BLOCK: 0 0 107 1121
TASKLET: 0 0 0 290
SCHED: 27035 26983 26971 26746
HRTIMER: 0 0 0 0
RCU: 1678 1769 2178 2250
另外mpstat也有软中断统计信息soft%
http://blog.yufeng.info/archives/2037/comment-page-1#comment-6249
https://github.com/torvalds/linux/blob/master/Documentation/networking/scaling.txt