1、关于多队列网卡

通过lspci方式查看网卡信息,如果有MSI-X, Enable+ 并且Count > 1,则该网卡是多队列网卡,多队列网卡内部会有多个 Ring Buffer。

[root@localhost ~]# lspci -vvv | grep -A50 "Ethernet controller" | grep -E "Capabilities|Ethernet controller"
01:00.0 Ethernet controller: Intel Corporation I350 Gigabit Network Connection (rev 01)Capabilities: [40] Power Management version 3Capabilities: [50] MSI: Enable- Count=1/1 Maskable+ 64bit+Capabilities: [70] MSI-X: Enable+ Count=10 Masked-Capabilities: [a0] Express (v2) Endpoint, MSI 00Capabilities: [e0] Vital Product Data

从以上信息可见,我们的这张网卡是支持多队列的。

2、网卡支持最大队列数及当前使用队列

我们可以通过ethtool命令查看网卡支持的最大队列数,

[root@localhost ~]# ethtool -l eth0
Channel parameters for eth0:
Pre-set maximums:
RX:     0
TX:     0
Other:      1
Combined:   63
Current hardware settings:
RX:     0
TX:     0
Other:      1
Combined:   40

由上可见,该网卡最多支持63个队列,当前使用了40个队列。为什么不开启63个队列呢,因为机器的CPU数没那么多,

[root@localhost ~]# cat /proc/cpuinfo | grep processor | wc -l
40

我们开启多队列的初衷就是为了利用多核。队列数和CPU相等,正好可以每个CPU处理一个队列,这样效率比较高。

3、修改网卡队列数

有时候网卡支持多队列却没有开启,那么就要手动设置网卡队列数,

ethtool -L eth0 combined 8

其中combined指的是网卡收发队列共用的情况,有些网卡可单独设置收发队列,

ethtool -L eth0 rx 8
ethtool -L eth0 tx 8

设置后可以在/sys/class/net/eth0/queues/目录下看到对应的队列,

[root@localhost ~]# cd /sys/class/net/eth0/queues/
[root@localhost queues]# ls
rx-0  rx-2  rx-4  rx-6  tx-0  tx-2  tx-4  tx-6
rx-1  rx-3  rx-5  rx-7  tx-1  tx-3  tx-5  tx-7

4、多队列网卡绑核

为了保证CPU均衡,也即是网卡中断能分配到各个CPU,我们通常会将网卡中断绑核,具体操作见——网卡中断均衡设置

5、单队列网卡

上面说的都是多队列网卡,那单队列的怎么搞呢,不能厚此薄彼吧。这时候就出现RPS和RFS了。简单来说就是在软件层面模拟多队列的情况,从而达到CPU均衡。

RPS(Receive Packet Steering)把软中断的负载均衡到各个cpu,是在单个CPU将数据从Ring Buffer取出来之后开始工作,网卡驱动通过四元组(SIP,SPORT,DIP,DPORT)生成一个hash值,然后根据这个hash值分配到对应的CPU上处理,从而发挥多核的能力。

但是还有个问题,由于RPS只是把数据包均衡到不同的cpu,但是收包的应用程序和软中断处理不一定是在同一个CPU,这样对于cpu cache的影响会很大。因此就出现RFS(Receive flow steering),它确保应用程序和软中断处理的cpu是同一个,从而能充分利用cpu的cache,这两个补丁往往都是一起设置,以达到最好的优化效果。

6、设置RPS

首先内核要开启CONFIG_RPS编译选项,然后设置需要将中断分配到哪些CPU,

 /sys/class/net/<dev>/queues/rx-<n>/rps_cpus

比如,要将eth0上0号收包软中断均匀分配到64个CPU上(假设机器上有这么多CPU),那么可以如下操作,

 echo "ffffffff,ffffffff" > /sys/class/net/eth0/queues/rx-0/rps_cpus

和多队列中断绑定规则类似,每个CPU用1位表示,因此1,2,4,8分别对应0-3号CPU,分配到这些CPU,相加就是15,即f。

如果只想分配到前32个CPU,则可以如下操作,

 echo "00000000,ffffffff" > /sys/class/net/eth0/queues/rx-0/rps_cpus

7、设置RFS

上面我们说过RPS和RFS一般要配合使用,效果才最优,因此RFS同样需要开启CONFIG_RPS编译选项,同时设置每个队列的数据流表总数才能真正生效。

这里我们了解一下RFS的细节:

RFS的实现需要依赖两个表——全局socket流表(rps_sock_flow_table)和设备流表(rps_dev_flow_table)。全局socket流表记录的是每个流由上面RPS计算通过hash分配的CPU号,也就是期望的CPU号;设备流表存在于每个网络设备的每个接收队列,表中记录的是每个未完成流使用的CPU号,也就是当前流使用的CPU号。具体使用哪个CPU简单来说有以下规则,

  • 如果两个表中记录的对应流使用的是同一个CPU号,就使用这个CPU
  • 如果当前流使用的CPU未设置或者CPU处于离线状态,那就使用期望CPU表中的CPU号,也就是RPS计算而得的CPU号
  • 如果两个表中对应流记录的CPU核不是同一个:
  • a)如果同一流的前一段数据包未处理完,为了避免乱序,不更换CPU,继续使用当前流使用的CPU号
  • b)如果同一流的前一段数据包已经处理完,那就可以使用期望CPU表中的CPU号

因此我们需要设置这两个表中记录的entry,对于全局socket流表(rps_sock_flow_table),该配置接口是

/proc/sys/net/core/rps_sock_flow_entries

而设备流表(rps_dev_flow_table)则通过以下接口设置,

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

两者的关系如下,

rps_sock_flow_entries = rps_flow_cnt * N

其中,N就是队列数量。因此,对于单队列网卡,两个值是一样的。

8、XPS(Transmit Packet Steering)

上面说的都是关于接收队列,那对于发送队列呢,这就需要用到XPS了。

XPS通过创建CPU到网卡发送队列的对应关系,来保证处理发送软中断请求的CPU和向外发送数据包的CPU是同一个CPU,用来保证发送数据包时候的局部性。

对于发送队列到CPU的映射有两种选择:

1、使用CPU映射
这种方式是通过指定发送队列在某几个CPU上处理,通过减小分发的CPU范围来减少锁开销以及cache miss。最常见的就是1对1,和上面说到的接收软中断绑核类似,通过以下接口设置,

/sys/class/net/<dev>/queues/tx-<n>/xps_cpus

同样是bitmaps方式。

2、接收队列映射方式
这种方式基于接收队列的映射来选择CPU,也就是说让接收队列和发送队列在同一个CPU,或指定范围的几个CPU来处理。这种方式对于多线程一直收发包的系统效果比较明显,收发包队列处理在同一个CPU,不仅减少了对其他CPU的打断,同时提高应用处理效率,收完包后直接在同个CPU继续发包,从而减小CPU消耗,同时减小包的时延。

这种方式映射,可通过一下接口设置(不是所有网卡都支持),

/sys/class/net/<dev>/queues/tx-<n>/xps_rxqs

另外,XPS对于单发送队列网卡没有效果,这个可想而知。


参考资料:
1、https://www.kernel.org/doc/Documentation/networking/scaling.txt

多队列网卡及RPS/RFS/XPS设置相关推荐

  1. linux 网络RPS/RFS/XPS

    1. 介绍 在网络非常 heavy 的情况下,对于文件服务器.高流量 Web 服务器这样的应用来说,把不同的网卡 IRQ 均衡绑定到不同的 CPU 上将会减轻某个 CPU 的负担,提高多个 CPU 整 ...

  2. Linux RSS/RPS/RFS/XPS对比

    RSS适合于多队列网卡,把不同的流分散的不同的网卡多列中,至于网卡队列由哪个cpu处理还需要绑定网卡队列中断与cpu RPS:适合于单队列网卡或者虚拟网卡,把该网卡上的数据流让多个cpu处理 RFS: ...

  3. [转]linux下基于SMP架构的多队列网卡的调优(Multi-queue network interfaces with SMP on Linux)

    转自: http://blog.csdn.net/vah101/article/details/38615795 在许多商业应用场景下,使用linux来搭建路由器是一种可选的方案.在这篇博文中,我们将 ...

  4. 高并发多队列网卡设置CPU亲和性项目记录

    之前我转载过一篇smp-affinity的文章https://blog.csdn.net/yue530tomtom/article/details/76216503 实例 做ssl加速卡(高并发)测试 ...

  5. RSS/RPS/RFS究竟是个什么东西

    RSS(Receive Side Scaling) 技术在网络数据接收时有效.具备RSS能力的网卡,有多个接收队列,网卡可以用不同的接收队列来接收不同的网络流,再将这些队列分配到不同的CPU核上进行处 ...

  6. Linux Kernel TCP/IP Stack — L1 Layer — 多队列网卡

    目录 文章目录 目录 多队列网卡 Intel 82575 的多队列硬件实现 Intel 82575 的多队列软件驱动实现 多队列网卡识别 多队列网卡 多队列网卡,是一种用来解决网络 I/O QoS 问 ...

  7. 虚拟机网卡(NAT模式)设置连接外网

    虚拟机网卡(NAT模式)设置连接外网 一.虚拟机VMWare三种网络模式 1.Bridged(桥接模式) 桥接模式相当于虚拟机和主机在同一个真实网段,VMWare充当一个集线器功能(一根网线连到主机相 ...

  8. centos 重启网卡_CentOS6 网络管理之网卡配置及简单路由设置

    CentOS6中关于网络配置的命令有很多,本文将介绍几个平时最长用的几个命令,以及网卡IP地址的配置和简单路由配置. 1.经常使用的查看IP地址命令为 ifconfig,不跟参数的情况下默认查看所有已 ...

  9. 雷电模拟器桥接模式不显示网卡,4版本不能设置代理

    版本3.121.0,点击安装驱动之后,提示成功: 但是这时候"桥接网卡"还是不能选中任何东西的... 如果这时候直接点保存设置,再运行模拟器,会出现崩溃: 点击一键修复 修复完成, ...

最新文章

  1. 在Jetson Xavier NX上安装pycuda报错:src/cpp/cuda.hpp:14:10: fatal error: cuda.h: No such file or directory
  2. 操作系统(三十二)内存的基础常识
  3. cctype,string,vector
  4. ASP.NET Web API随记汇总
  5. ML.NET 发布0.11版本:.NET中的机器学习,为TensorFlow和ONNX添加了新功能
  6. python字节流分割_Python 字节流,字符串,十六进制相互转换实例(binascii,bytes)
  7. 《转》常用的正则表达式
  8. 在同一个公司死磕5-10年,到底值不值得?
  9. Oracle函数——日期函数
  10. 实验二:大数据可视化工具-Tableau
  11. 孙式太极拳的站桩(作者:孙剑云)
  12. PS图层混合模式实例详解
  13. Shake Shack上海第7家门店开业
  14. C语言 本地套接字这个审核也不给我通过,老规矩base64
  15. CyberArk被评为2022年Gartner特权访问管理魔力象限领导者
  16. Win11如何自动清理垃圾?Win11自动删除文件设置方法
  17. 二叉树的中序遍历,前序遍历,后序遍历
  18. 怎么判断手机天线坏了_如何确认iphone6wifi天线坏了
  19. Dobot magician + realsense D435i 手眼标定(外参)C++
  20. 计算机机房坏境设施演练,计算机机房环境设施应急演练方案.doc

热门文章

  1. 教你使用python在终端创建炫酷二维码!!!
  2. earlier的意思_单词earlier具体是什么意思
  3. 奇迹控制器证实配置登录器详解
  4. 所见所得的OFFICE功能区编辑器(自定义界面编辑)RibbonCreator
  5. dell电脑更新win11后黑屏但有鼠标(已解决)
  6. Validation 使用
  7. vue3使用swiper+animate.css动效
  8. 快速排序的三种分区方法(整理)
  9. AI:2020年6月23日北京智源大会演讲分享之AI创业专题论坛——10:30-11:20陆奇教授《AI创业发展趋势:机会与挑战》
  10. 碧蓝航线内部表情包(有爱自取)