2010-12-22 22:21:00 uestc_huan 阅读数 8484

最近看到一个用Linux内核的多队列收包与流控制技术RPS/RFS来平衡cpu负载的资料。当网络负载很重时,多cpu系统中,cpu0由于处理网卡中断,会导致cpu0负荷非常重。而其他cpu负荷相对要轻很多。此时,就可以用rps/rfs来平衡各个cpu的负载。具体还需要再仔细去查下资料。这里先mark一下。

 

2012-07-03 10:33:05 maijian 阅读数 11241

http://www.igigo.net/archives/204


Linux内核 RPS/RFS功能详细测试分析

RPS和RFS

  • RPS 全称是 Receive Packet Steering, 这是Google工程师 Tom Herbert (therbert@google.com )提交的内核补丁, 在2.6.35进入Linux内核. 这个patch采用软件模拟的方式,实现了多队列网卡所提供的功能,分散了在多CPU系统上数据接收时的负载, 把软中断分到各个CPU处理,而不需要硬件支持,大大提高了网络性能。
  • RFS 全称是 Receive Flow Steering, 这也是Tom提交的内核补丁,它是用来配合RPS补丁使用的,是RPS补丁的扩展补丁,它把接收的数据包送达应用所在的CPU上,提高cache的命中率。
  • 这两个补丁往往都是一起设置,来达到最好的优化效果, 主要是针对单队列网卡多CPU环境(多队列多重中断的网卡也可以使用该补丁的功能,但多队列多重中断网卡有更好的选择:SMP IRQ affinity)

原理

RPS: RPS实现了数据流的hash归类,并把软中断的负载均衡分到各个cpu,实现了类似多队列网卡的功能。由于RPS只是单纯的把同一流的数据包分发给同一个CPU核来处理了,但是有可能出现这样的情况,即给该数据流分发的CPU核和执行处理该数据流的应用程序的CPU核不是同一个:数据包均衡到不同的cpu,这个时候如果应用程序所在的cpu和软中断处理的cpu不是同一个,此时对于cpu cache的影响会很大。那么RFS补丁就是用来确保应用程序处理的cpu跟软中断处理的cpu是同一个,这样就充分利用cpu的cache。
  • 应用RPS之前: 所有数据流被分到某个CPU, 多CPU没有被合理利用, 造成瓶颈

  • 应用RPS之后: 同一流的数据包被分到同个CPU核来处理,但可能出现cpu cache迁跃

  • 应用RPS+RFS之后: 同一流的数据包被分到应用所在的CPU核

必要条件

使用RPS和RFS功能,需要有大于等于2.6.35版本的Linux kernel.

如何判断内核版本?
1
2
$ uname -r
2.6.38-2-686-bigmem

对比测试

类别 测试客户端 测试服务端
型号 BladeCenter HS23p BladeCenter HS23p
CPU Xeon E5-2609 Xeon E5-2630
网卡 Broadcom NetXtreme II BCM5709S Gigabit Ethernet Emulex Corporation OneConnect 10Gb NIC
内核 3.2.0-2-amd64 3.2.0-2-amd64
内存 62GB 66GB
系统 Debian 6.0.4 Debian 6.0.5
超线程
CPU核 4 6
驱动 bnx2 be2net
  • 客户端: netperf
  • 服务端: netserver
  • RPS cpu bitmap测试分类: 0(不开启rps功能), one cpu per queue(每队列绑定到1个CPU核上), all cpus per queue(每队列绑定到所有cpu核上), 不同分类的设置值如下
  1. 0(不开启rps功能)
    /sys/class/net/eth0/queues/rx-0/rps_cpus 00000000
    /sys/class/net/eth0/queues/rx-1/rps_cpus 00000000
    /sys/class/net/eth0/queues/rx-2/rps_cpus 00000000
    /sys/class/net/eth0/queues/rx-3/rps_cpus 00000000
    /sys/class/net/eth0/queues/rx-4/rps_cpus 00000000
    /sys/class/net/eth0/queues/rx-5/rps_cpus 00000000
    /sys/class/net/eth0/queues/rx-6/rps_cpus 00000000
    /sys/class/net/eth0/queues/rx-7/rps_cpus 00000000
    
    /sys/class/net/eth0/queues/rx-0/rps_flow_cnt 0
    /sys/class/net/eth0/queues/rx-1/rps_flow_cnt 0
    /sys/class/net/eth0/queues/rx-2/rps_flow_cnt 0
    /sys/class/net/eth0/queues/rx-3/rps_flow_cnt 0
    /sys/class/net/eth0/queues/rx-4/rps_flow_cnt 0
    /sys/class/net/eth0/queues/rx-5/rps_flow_cnt 0
    /sys/class/net/eth0/queues/rx-6/rps_flow_cnt 0
    /sys/class/net/eth0/queues/rx-7/rps_flow_cnt 0
    
    /proc/sys/net/core/rps_sock_flow_entries 0
  2. one cpu per queue(每队列绑定到1个CPU核上)
    /sys/class/net/eth0/queues/rx-0/rps_cpus 00000001
    /sys/class/net/eth0/queues/rx-1/rps_cpus 00000002
    /sys/class/net/eth0/queues/rx-2/rps_cpus 00000004
    /sys/class/net/eth0/queues/rx-3/rps_cpus 00000008
    /sys/class/net/eth0/queues/rx-4/rps_cpus 00000010
    /sys/class/net/eth0/queues/rx-5/rps_cpus 00000020
    /sys/class/net/eth0/queues/rx-6/rps_cpus 00000040
    /sys/class/net/eth0/queues/rx-7/rps_cpus 00000080
    
    /sys/class/net/eth0/queues/rx-0/rps_flow_cnt 4096
    /sys/class/net/eth0/queues/rx-1/rps_flow_cnt 4096
    /sys/class/net/eth0/queues/rx-2/rps_flow_cnt 4096
    /sys/class/net/eth0/queues/rx-3/rps_flow_cnt 4096
    /sys/class/net/eth0/queues/rx-4/rps_flow_cnt 4096
    /sys/class/net/eth0/queues/rx-5/rps_flow_cnt 4096
    /sys/class/net/eth0/queues/rx-6/rps_flow_cnt 4096
    /sys/class/net/eth0/queues/rx-7/rps_flow_cnt 4096
    
    /proc/sys/net/core/rps_sock_flow_entries 32768
  3. all cpus per queue(每队列绑定到所有cpu核上)
    /sys/class/net/eth0/queues/rx-0/rps_cpus 000000ff
    /sys/class/net/eth0/queues/rx-1/rps_cpus 000000ff
    /sys/class/net/eth0/queues/rx-2/rps_cpus 000000ff
    /sys/class/net/eth0/queues/rx-3/rps_cpus 000000ff
    /sys/class/net/eth0/queues/rx-4/rps_cpus 000000ff
    /sys/class/net/eth0/queues/rx-5/rps_cpus 000000ff
    /sys/class/net/eth0/queues/rx-6/rps_cpus 000000ff
    /sys/class/net/eth0/queues/rx-7/rps_cpus 000000ff
    
    /sys/class/net/eth0/queues/rx-0/rps_flow_cnt 4096
    /sys/class/net/eth0/queues/rx-1/rps_flow_cnt 4096
    /sys/class/net/eth0/queues/rx-2/rps_flow_cnt 4096
    /sys/class/net/eth0/queues/rx-3/rps_flow_cnt 4096
    /sys/class/net/eth0/queues/rx-4/rps_flow_cnt 4096
    /sys/class/net/eth0/queues/rx-5/rps_flow_cnt 4096
    /sys/class/net/eth0/queues/rx-6/rps_flow_cnt 4096
    /sys/class/net/eth0/queues/rx-7/rps_flow_cnt 4096
    
    /proc/sys/net/core/rps_sock_flow_entries 32768

测试方法: 每种测试类型执行3次,中间睡眠10秒, 每种测试类型分别执行100、500、1500个实例, 每实例测试时间长度为60秒

  • TCP_RR 1 byte: 测试TCP 小数据包 request/response的性能
    1
    netperf -t TCP_RR -H $serverip -c -C -l 60
  • UDP_RR 1 byte: 测试UDP 小数据包 request/response的性能
    1
    netperf -t UDP_RR -H $serverip -c -C -l 60
  • TCP_RR 256 byte: 测试TCP 大数据包 request/response的性能
    1
    netperf -t TCP_RR -H $serverip -c -C -l 60 -- -r256,256
  • UDP_RR 256 byte: 测试UDP 大数据包 request/response的性能
    1
    netperf -t UDP_RR -H $serverip -c -C -l 60 -- -r256,256

TPS测试结果

  • TCP_RR 1 byte小包测试结果

  • TCP_RR 256 byte大包测试结果

  • UDP_RR 1 byte小包测试结果

  • UDP_RR 256 byte大包测试结果

CPU负载变化

在测试过程中,使用mpstat收集各个CPU核的负载变化

  1. 关闭RPS/RFS: 可以看出关闭RPS/RFS时,软中断的负载都在cpu0上,并没有有效的利用多CPU的特性,导致了性能瓶颈
    Average:     CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
    Average:     all    3.65    0.00   35.75    0.05    0.01   14.56    0.00    0.00   45.98
    Average:       0    0.00    0.00    0.00    0.00    0.00  100.00    0.00    0.00    0.00
    Average:       1    4.43    0.00   37.76    0.00    0.11   11.49    0.00    0.00   46.20
    Average:       2    5.01    0.00   45.80    0.00    0.00    0.00    0.00    0.00   49.19
    Average:       3    5.11    0.00   45.07    0.00    0.00    0.00    0.00    0.00   49.82
    Average:       4    3.52    0.00   40.38    0.14    0.00    0.00    0.00    0.00   55.96
    Average:       5    3.85    0.00   39.91    0.00    0.00    0.00    0.00    0.00   56.24
    Average:       6    3.62    0.00   40.48    0.14    0.00    0.00    0.00    0.00   55.76
    Average:       7    3.87    0.00   38.86    0.11    0.00    0.00    0.00    0.00   57.16
  2. 每队列关联到一个CPU TCP_RR: 可以看出软中断负载已经能分散到各个CPU核上,有效利用了多CPU的特性,大大提高了系统的网络性能
    Average:     CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
    Average:     all    5.58    0.00   59.84    0.01    0.00   22.71    0.00    0.00   11.86
    Average:       0    2.16    0.00   20.85    0.00    0.04   72.03    0.00    0.00    4.93
    Average:       1    4.68    0.00   46.27    0.00    0.00   42.73    0.00    0.00    6.32
    Average:       2    6.76    0.00   63.79    0.00    0.00   11.03    0.00    0.00   18.42
    Average:       3    6.61    0.00   65.71    0.00    0.00   11.51    0.00    0.00   16.17
    Average:       4    5.94    0.00   67.83    0.07    0.00   11.59    0.00    0.00   14.58
    Average:       5    5.99    0.00   69.42    0.04    0.00   12.54    0.00    0.00   12.01
    Average:       6    5.94    0.00   69.41    0.00    0.00   12.86    0.00    0.00   11.78
    Average:       7    6.13    0.00   69.61    0.00    0.00   14.48    0.00    0.00    9.77
  3. 每队列关联到一个CPU UDP_RR: CPU负载未能均衡的分布到各个CPU, 这是由于网卡hash计算在UDP包上的不足, 详细请见本文后记部分
    Average:     CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
    Average:     all    3.01    0.00   29.84    0.07    0.01   13.35    0.00    0.00   53.71
    Average:       0    0.00    0.00    0.08    0.00    0.00   90.01    0.00    0.00    9.91
    Average:       1    3.82    0.00   32.87    0.00    0.05   12.81    0.00    0.00   50.46
    Average:       2    4.84    0.00   37.53    0.00    0.00    0.14    0.00    0.00   57.49
    Average:       3    4.90    0.00   37.92    0.00    0.00    0.16    0.00    0.00   57.02
    Average:       4    2.57    0.00   32.72    0.20    0.00    0.09    0.00    0.00   64.42
    Average:       5    2.66    0.00   33.54    0.11    0.00    0.08    0.00    0.00   63.60
    Average:       6    2.75    0.00   32.81    0.09    0.00    0.06    0.00    0.00   64.30
    Average:       7    2.71    0.00   32.66    0.17    0.00    0.06    0.00    0.00   64.40
  4. 每队列关联到所有CPU: 可以看出软中断负载已经能分散到各个CPU核上,有效利用了多CPU的特性,大大提高了系统的网络性能
    Average:     CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
    Average:     all    5.39    0.00   59.97    0.00    0.00   22.57    0.00    0.00   12.06
    Average:       0    1.46    0.00   21.83    0.04    0.00   72.08    0.00    0.00    4.59
    Average:       1    4.45    0.00   46.40    0.00    0.04   43.39    0.00    0.00    5.72
    Average:       2    6.84    0.00   65.62    0.00    0.00   11.39    0.00    0.00   16.15
    Average:       3    6.71    0.00   67.13    0.00    0.00   12.07    0.00    0.00   14.09
    Average:       4    5.73    0.00   66.97    0.00    0.00   10.71    0.00    0.00   16.58
    Average:       5    5.74    0.00   68.57    0.00    0.00   13.02    0.00    0.00   12.67
    Average:       6    5.79    0.00   69.27    0.00    0.00   12.31    0.00    0.00   12.63
    Average:       7    5.96    0.00   68.98    0.00    0.00   12.00    0.00    0.00   13.06

结果分析

以下结果只是针对测试服务器特定硬件及系统的数据,在不同测试对象的RPS/RFS测试结果可能有不同的表现

TCP性能:

  • 在没有打开RPS/RFS的情况下,随着进程数的增加,TCP tps性能并明显没有提升,在184~188k之间。
  • 打开RPS/RFS之后,随着RPS导致软中断被分配到所有CPU上和RFS增加的cache命中, 小数据包(1字节)及大数据包(256字节,相对小数据包而言, 而不是实际应用中的大数据包)的tps性能都有显著提升
  • 100个进程提升40%的性能(两种RPS/RFS设置的性能结果一致), cpu负载升高40%
  • 500个进程提升70%的性能(两种RPS/RFS设置的性能结果一致), cpu负载升高62%
  • 1500个进程提升75%的性能(两种RPS/RFS设置的性能结果一致), cpu负载升高77%


UDP性能:

  • 在没有打开RPS/RFS的情况下,随着进程数的增加,UDP tps性能并明显没有提升,在226~235k之间。
  • 打开RPS/RFS之后,,随着RPS导致软中断被分配到所有CPU上和RFS增加的cache命中, 小数据包(1字节)及大数据包(256字节,相对小数据包而言, 而不是实际应用中的大数据包)的TPS性能, 在每队列关联到所有CPU的情况下有显著提升, 而每队列关联到一个CPU后反倒是导致了UDP tps性能下降1% (这是bnx2网卡不支持UDP port hash及此次测试的局限性造成的结果, 详细分析见: 后记)
  • 每队列关联到所有CPU的情况下, 在100个进程时小包提升40%的性能, cpu负载升高60%; 大包提升33%, cpu负载升高47%
  • 每队列关联到所有CPU的情况下, 在500个进程提小包提升62%的性能, cpu负载升高71%; 大包提升60%, cpu负载升高65%
  • 每队列关联到所有CPU的情况下, 在1500个进程提升65%的性能, cpu负载升高75%; 大包提升64%, cpu负载升高74%

后记

UDP在每队列绑定到一个CPU时性能下降,而绑定到所有CPU时,却有性能提升,这一问题涉及到几个因素,当这几个因素凑一起时,导致了这种奇特的表现。

  • 此次测试的局限性:本次测试是1对1的网络测试,产生的数据包的IP地址都是相同的
  • bnx2网卡在RSS hash上,不支持UDP Port,也就是说,网卡在对TCP数据流进行队列选择时的hash包含了ip和port, 而在UDP上的hash, 只有IP地址,导致了本次测试(上面的局限性影响)的UDP数据包的hash结果都是一样的,数据包被转送到同一条队列。
  • 单单上面两个因素,还无法表现出UDP在每队列绑定到一个CPU时性能下降,而绑定到所有CPU时,却有性能提升的现象。 因为RPS/RFS本身也有hash计算,也就是进入队列后的数据包,还需要经过RPS/RFS的hash计算(这里的hash支持udp port), 然后进行第二次数据包转送选择;如果每队列绑定到一个CPU, 系统直接跳过第二次hash计算,数据包直接分配到该队列关联的CPU处理,也就导致了在第一次hash计算后被错误转送到某一队列的UDP数据包,将直接送到cpu处理,导致了性能的下降; 而如果是每队列绑定到所有CPU, 那么进入队列后的数据包会在第二次hash时被重新分配,修正了第一次hash的错误选择。

相关对比测试

1. SMP IRQ affinity: http://www.igigo.net/archives/231

参考资料



2018-04-21 09:07:16 dog250 阅读数 12138

本文快速解析一下RPS/RFS的基本原理。

RPS-Receive Packet Steering

下面这个就是RPS的原理:
这里写图片描述

其实就是一个软件对CPU负载重分发的机制。其使能的作用点在CPU开始处理软中断的开始,即下面的地方:

netif_rx_internal
netif_receive_skb_internal

RFS-Receive Flow Steering

RFS在RPS的基础上,充分考虑到同一个五元组flow进程上下文和软中断上下文之间处理CPU的一致性,为此在socket层面也要有相应的处理。

  非常遗憾的是,一张图无法把这一切全部表达,那么我们分阶段进行,首先看同一个五元组flow第一个包到达的情形:
这里写图片描述

显然,global mapping作为全局映射,空间必须足够大才能容纳足够多的流,不然会相互覆盖。我建议设置成最大并发连接数的2倍。

  然后,当同一个flow的后续包到来时,我们看一下global mapping如何起作用。先来看后续第一个包到来时的情景:

这里写图片描述

仔细看图,这里增加了一个Per Queue Hash map,这些map是从global map生成的,此后的数据包再到达时,就可以查这个map了:

这里写图片描述

然而,这并没有看出来RFS和RPS的不同。

  你能保证处理softirq和处理socket的是同一个CPU吗?你不能,有可能tcp_v4_rcv是CPU0在处理,然后在data_ready中把socket进程唤醒,然而调度器将进程wakeup到CPU1上了,这样在update global hash map的时候,就会更新一个不同的CPU,这个时候RFS的作用就体现了,RFS会把Per Queue Hash Map也更新了,进而接下来的数据包会全部重定向到新的CPU上,然而RPS并不会这么做。

  RFS也不是只要发现CPU变了就无条件切换,而是要满足一个条件,即:
同一个流上次enqueue到旧CPU的数据包全部被处理完毕
如此可以保证同一个流处理的串行性,同时处理协议头的时候还能充分利用Hot cacheline。

Accelerated RFS

基本就是可以把软件发现的配置反向注入到硬件,需要硬件支持,不多说。


本文只讲原理,想知道Howto,请参考内核源码包Documentation/networking/scaling.txt文件。


trick and tips

有时候太均匀太平等了并不是好事。

  在CPU运行繁重的用户态业务逻辑的时候,把中断打到同一个CPU上反而有一个天然限流的作用,要注意,先要找到瓶颈在哪里。如果瓶颈在业务逻辑的处理,那么当你启用RPS/RFS之后,你会发现用户态服务指标毫无起色,同时发现softirq飙高,这并不是一件好事。

  参考下面的图示:
这里写图片描述

这样好吗?为了所谓内核态处理的优雅均衡,挤压了用户态的CPU时间,这是典型的初学者行为,为了内核而优化内核,典型的物业殴打业主!

  其实,OS内核的作用只有一个,就是服务用户态业务逻辑的处理!

  不多说。

2017-02-23 16:12:53 u012385733 阅读数 554

http://blog.chinaunix.net/uid-20788636-id-4838269.html

1  RPS/RFS 介绍

1.1 RPS/RFS出现的原因

RPS/RFS 功能是在Linux- 2.6.35中有google的工程师提交的两个补丁,这两个补丁的出现主要是基于以下两点现实的考虑:

1       这两个补丁的出现,是由于服务器的CPU越来越强劲,可以到达十几核、几十核,而网卡硬件队列则才4个、8个,这种发展的不匹配造成了CPU负载的不均衡。

2       上面的提到的是多队列网卡的情况,在单队列网卡的情况下,RPS/RFS相当于在系统层用软件模拟了多队列的情况,以便达到CPU的均衡。

出现RFS/RPS的原因主要是由于过多的网卡收包和发包中断集中在一个CPU上,在系统繁忙时,CPU对网卡的中断无法响应,这样导致了服务器端的网络性能降低,从这里可以看出其实网络性能的瓶颈不在于网卡,而是CPU,因为现在的网卡很多都是万兆并且多队列的,如果有过多的中断集中在一个CPU上,将导致该CPU无法处理,所以可以使用该方法将网卡的中断分散到各个CPU上。但对于CentOS 6.1已经支持了。

1.2 多队列网卡

当网卡驱动加载时,通过获取的网卡型号,得到网卡的硬件queue的数量,并结合CPU核的数量,最终通过Sum=Min(网卡queueCPU core)得出所要激活的网卡queue数量(Sum),并申请Sum个中断号,分配给激活的各个queue,当某个queue收到报文时,触发相应的中断,收到中断的核,将该任务加入到协议栈负责收包的该核的NET_RX_SOFTIRQ队列中(NET_RX_SOFTIRQ在每个核上都有一个实例),在NET_RX_SOFTIRQ中,调用NAPI的收包接口,将报文收到有多个netdev_queuenet_device数据结构中。

CPU可以平行收包时,就会出现不同的核收取了同一个queue的报文,这就会产生报文乱序的问题,解决方法是将一个queue的中断绑定到唯一的一个核上去,从而避免了乱序问题。

查看网卡是否支持MSI-X可以直接查看 interrupts 文件,看关键字 MSI 就知道了:

# grep -i msi /proc/interrupts

Broadcom的网卡手册上有关于MSIMSI-X的定义:

MSI Version. This is the Message Signaled Interrupts (MSI) version beingused. The option MSI corresponds to the PCI 2.2 specification that supports 32messages and a single MSI address value. The option MSI-X corresponds to thePCI 3.0 specification that supports 2,048 messages and an independent messageaddress for each message.

实际应用场景中,MSI方式的中断对多核cpu的利用情况不佳,网卡中断全部落在某一个cpu上,即使设置cpu affinity也没有作用,而MSI-X中断方式可以自动在多个cpu上分担中断。

1.3 RPS/RFS介绍

RPSReceive Packet Steering)主要是把软中断的负载均衡到各个cpu,简单来说,是网卡驱动对每个流生成一个hash标识,这个HASH值得计算可以通过四元组来计算(SIPSPORTDIPDPORT),然后由中断处理的地方根据这个hash标识分配到相应的CPU上去,这样就可以比较充分的发挥多核的能力了。通俗点来说就是在软件层面模拟实现硬件的多队列网卡功能,如果网卡本身支持多队列功能的话RPS就不会有任何的作用。该功能主要针对单队列网卡多CPU环境,如网卡支持多队列则可使用SMP irq affinity直接绑定硬中断。


只有RPS的情况下(来源网络)

由于RPS只是单纯把数据包均衡到不同的cpu,这个时候如果应用程序所在的cpu和软中断处理的cpu不是同一个,此时对于cpu cache的影响会很大,那么RFSReceive flow steering)确保应用程序处理的cpu跟软中断处理的cpu是同一个,这样就充分利用cpucache,这两个补丁往往都是一起设置,来达到最好的优化效果主要是针对单队列网卡多cpu的环境。


2:同时开启RPS/RFS后(来源网络)

rps_flow_cntrps_sock_flow_entries,参数的值会被进位到最近的2的幂次方值,对于单队列设备,单队列的rps_flow_cnt值被配置成与 rps_sock_flow_entries相同。

RFS依靠RPS的机制插入数据包到指定CPUbacklog队列,并唤醒那个CPU来执行

1.4 RSS介绍

RSSreceive side scaling)是有微软提处理,通过这项技术能够将网络流量分载到多个cpu上,降低单个cpu的占用率。默认情况下,每个cpu核对应一个rss队列。ixgbe驱动将收到的数据包的源、目的ip地址和端口号,交由网卡硬件计算出一个rss hash值,再根据这个hash值来决定将数据包分配到哪个队列中。通过cat /proc/interrupts |grep 网卡名的方式,就可以看到网卡使用了几个rss通道。

RSS(Receive-side scaling,接收端调节)技术,RSS是和硬件相关联的,必须要有网卡的硬件进行支持,RSS把发数据包分配到不同的队列中,其中HASH值的计算式在硬件中完成的,然后通过affinity的调整把不同的中断映射的不同的Core上。下面是Linux内核对RFSRSS描述。

For a multi-queue system, if RSS is configured so that a hardware

receive queue is mapped to each CPU, then RPS is probably redundant

and unnecessary. If there are fewer hardware queues than CPUs, then

RPS might be beneficial if the rps_cpus for each queue are the ones that

share the same memory domain as the interrupting CPU for that queue.

Intel架构上的一些硬件上是有该功能的。

On the Intel architecture, multi-queue NICs use MSI-X (the extendedversion of Message Signaled Interrupts) to send interrupts to multiple cores.The feature that distributes arriving packets to different CPUs based on(hashed) connection identifiers is called RSS (Receive Side Scaling) on Inteladapters, and its kernel-side support on Windows was introduced as part ofthe Scalable Networking Pack in Windows 2003 SP2.

This performanceenhancement works as follows: Incoming packets are distributed over multiplelogical CPUs (e.g. cores) based on a hash over the source and destination IPaddresses and port numbers. This hashing ensures that packets from the samelogical connection (e.g. TCP connection) are always handled by the sameCPU/core. On some network adapters, the work of computing the hash can beoutsourced to the network adapter. For example, some Intel and Myricom adapterscompute a Toeplitz hashfrom these header fields. This has thebeneficial effect of avoiding cache misses on the CPU that performs thesteering - the receiving CPU will usually have to read these fields anyway.

Receive-Side Scaling (RSS), also known as multi-queue receive, distributesnetwork receive processing across several hardware-based receive queues,allowing inbound network traffic to be processed by multiple CPUs. RSS can beused to relieve bottlenecks in receive interrupt processing caused byoverloading a single CPU, and to reduce network latency。(https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Performance_Tuning_Guide/network-rss.html

通过上面的介绍可以知道,对于RSSRFS的区别,它们都是把同一个流的数据包给同一个CPU,但是RSS是使用硬件实现的,而RFS是纯软件实现的。

1.5  网卡的affinity特性

SMP IRQ affinity Linux 2.4内核之后引入了将特定中断绑定到指定的CPU的技术,称为SMP IRQ affinity

smp_affinity是否需要设置,根据网卡是否支持多队列,如果网卡支持多队列则设置才有作用,如果网卡有多队列,就会有多个中断号,这样就可以把不同的中断号分配到不同CPU上,这样中断号就能相对均匀的分配到不同的CPU上。

这里简单的理解一下,smp_affinity值得映射关系,下面简单的举个例子:

如果cat  /proc/irq/84/smp_affinity的值为:20(二进制为:00100000),则84这个IRQ的亲和性为#5CPU

每个IRQ的默认的smp affinity在这里:cat /proc/irq/default_smp_affinity,默认值是全F

但是对于单队列的网卡配置「smp_affinity」和「smp_affinity_list」对多CPU无效。

1.6 总结

如果是单队列的话/proc/sys/net/core/rps_sock_flow_entries值和rps_flow_cnt设置为相同,rps更多的是针对网卡驱动是NAPI方式的,如果应用场景更多是内核的forwardRPS就足够了,再在该基础上使用RFS也不会有性能的提升。

在执行脚本向/sys/class/net/eth0/queues/rx-0/rps_cpus文件中写对应的数据时,提示

./set_irq_affinity.sh

./set_irq_affinity.sh: line 52: echo: write error: Value too large fordefined datatype                 

这是由于rps_cpus文件中的数,需要和CPU的个数相匹配,当写入的数据大于CPU的个数时,会出现上面的错误提示信息。

使用举例

可使用逗号为不连续的 32 位组限定 smp_affinity 值。在有 32 个以上核的系统有这个要求。例如:以下示例显示在一个 64 核系统的所有核中提供 IRQ 40

# cat /proc/irq/40/smp_affinity

ffffffff,ffffffff

 64 核系统的上 32 核中提供 IRQ 40,请执行:

# echo 0xffffffff,00000000 > /proc/irq/40/smp_affinity

# cat /proc/irq/40/smp_affinity

ffffffff,00000000

 

RFS需要内核编译CONFIG_RPS选项,RFS才起作用。全局数据流表(rps_sock_flow_table)的总数可以通过下面的参数来设置:

 /proc/sys/net/core/rps_sock_flow_entries

每个队列的数据流表总数可以通过下面的参数来设置:

 /sys/class/net/<dev>/queues/rx/rps_flow_cnt

echo ff > /sys/class/net//queues/rx-/rps_cpus

echo 4096 > /sys/class/net//queues/rx-/rps_flow_cnt

echo 30976 > /proc/sys/net/core/rps_sock_flow_entries

对于2个物理cpu,8核的机器为ff,具体计算方法是第一颗cpu00000001,第二个cpu00000010,第3cpu 00000100,依次类推,由于是所有的cpu都负担,所以所有的cpu数值相加,得到的数值为11111111,十六进制就刚好是ff。而对于 /proc/sys/net/core/rps_sock_flow_entries的数值是根据你的网卡多少个通道,计算得出的数据,例如你是8通道的网卡,那么1个网卡,每个通道设置4096的数值,8*4096就是/proc/sys/net/core/rps_sock_flow_entries 的数值,对于内存大的机器可以适当调大rps_flow_cnt

参考文献:

http://blog.csdn.net/turkeyzhou/article/details/7528182

http://lwn.net/Articles/328339/


没有更多推荐了,返回首页