Linux 操作系统原理 — RSS 多队列网卡

目录

RSS 多队列网卡

在以往,一张 NIC 只具有一个 Rx Queue,对应一个 CPU Core 来进行收包处理。在多核时代,为了充分利用 Multi-CPU Cores,NIC 也相应的提供了 Multi-Queue(多队列)功能。

结合 NIC RSS(Receive Side Scaling,接收侧扩展)功能,可以将多个 Rx Queues 通过硬中断绑定到不同的 CPU cores 上处理,以此均衡利用 CPU 资源并提高网络吞吐量。例如:Intel 82599 NIC 有 16 个 Queues,可以分别将每个 Queue 的中断号绑定到 16 个 CPU Cores 上。

此外,有些 NIC 还能够同时支持 Multi-Queue Receive 和 Multi-Queue Transmit。

RSS 技术实现原理

RSS Filter

在这里插入图片描述

NIC 通过 HW Filters(过滤器)来分发报文,Filters 首先会将报文分配给某条 Stream(逻辑流),然后将每条 逻辑流 中的报文都被导向不同的 Receive Queues,然后再由不同 CPU Cores 处理。

以 Intel 82599 NIC 为例,有以下 HW Filters 类型:

  1. L2 filter
  2. MAC filter
  3. VLAN filter
  4. L2 type filter
  5. Syn filter
  6. 5-Tuple filter
  7. Flow dirctor
  8. RSS

如上图,当报文经过了一系列 Filters,最后再交由 RSS 处理。

在这里插入图片描述

RSS HASH

在这里插入图片描述

RSS Hash function(e.g. Toeplitz HASH),通过计算 Incoming traffic 中的 Hash type specified(2-3-4-Tuple)得到一个 Hash value,然后再取出 Hash value 中的 LSBs(最低有效位。7bits)去 Lookup Indirection table(RETA,间接寻址表)找到这条 Traffic Flow 对应的 Rx queue。

同时,Hash type specified 和 Indirection table entries 都是可以被 Ethernet driver 或 ethtool CLI 进行编程的。

  • Hash type specified:可以是以下类型。

    • IP 2-tuple(srcIP、dstIP)
    • TCP/UDP 3-tuple(srcIP、dstIP、dstPort)
    • TCP/UDP 4-tuple(srcIP、dstIP、srcPort、dstPort)
  • Indirection table entries:具有 128 个条目,对应 128 个不同的 Queues,还可以设置不同的权重参数。

在这里插入图片描述

在这里插入图片描述

硬中断信号绑定

为了避免 Multi-Queues 导致的报文乱序问题,以及均衡的发挥多核处理器平台的并行能力,通常会通过硬件中断信号绑定的方式将 Multi-Queues 绑定到相应的 CPU Cores 上,结合 RSS 技术,实现将同一条 Flow 的 Traffic 总是交给相同的 Rx Queue 以及相同的 CPU Core 处理。

Linux Kernel v2.6.21 开始支持多队列网卡特性。在 NIC Driver 初始化流程中,Kernel 获悉 net_device 所支持的 Rx/Tx Queue 得数量。然后结合 CPU Cores 的数量,通过 Sum=Min(NIC Queue, CPU Core) 公式计算得出应该被激活 Sum 个 Queues,并申请 Sum 个 IRQ Numbers(硬中断请求号),分配给激活的每个 Queues。

多队列网卡通常采用 MSI-X(Message Signaled Interrupts X,消息信令中断)中断类型。MSI-X 支持为每个 NIC 分配多个 IRQ Numbers,使得每个 Rx Queues 都具有独立的 IRQ Number,因此可以绑定到不同的 CPU Cores 上。

在这里插入图片描述

处理 Rx Queue 硬中断的 CPU Core 也是随后进行处理收包的 CPU Core,如上图所示,当某个 NIC Rx Queue 收到 Frames 时,就触发自己的 IRQ,收到 IRQ 的 CPU Core 就执行 IRQ Number 对应的硬中断处理程序,最终将收包任务下发给该 Core 的 NET_RX_SOFTIRQ 实例处理(每个 Core 都有一个 NET_RX_SOFTIRQ 实例)。

在 NET_RX_SOFTIRQ 中会调用 NAPI 的收包接口,将 Frames 收到具有多个 netdev_queue 的 net_device 结构体中。

在这里插入图片描述

查看网卡启用的中断类型,如下图 MSI-X: Enable+。

$ lspci -vvv

在这里插入图片描述

可以使用 cat /proc/interrupts 查看 IPQs 的 Queue mappings 关系。

下面截选了 Network interface ens192 在每个 CPU cores 上的 IRQs 和 Queues 关系。可以看见,ens192 在 8 个 Cores 上都有中断处理,这是 IRQ 负载均衡器 irqbalance Daemon 作用的结果,但是这种均衡在高性能应用场景并不是最佳实践。例如在 DPDK 场景中,应该将 Queue 绑定到指定的 Core 上。

$ cat  /proc/interrupts
           CPU0       CPU1       CPU2       CPU3       CPU4       CPU5       CPU6       CPU7
...
 57:      20342      30923      33789      25533      46977      64504      78884      70780   PCI-MSI-edge      ens192-rxtx-0
 58:       5162       6797      10395      11019      17324      19285      21365      24282   PCI-MSI-edge      ens192-rxtx-1
 59:      14154      21925      28098      25550      48416      46239      59652      67793   PCI-MSI-edge      ens192-rxtx-2
 60:        429        836        924       1155       1917       2304       2227       3131   PCI-MSI-edge      ens192-rxtx-3
 61:       6667      16537      23922      20526      34824      38050      48226      43089   PCI-MSI-edge      ens192-rxtx-4
 62:        218        617       1149       1235       2559       2551       2098       3710   PCI-MSI-edge      ens192-rxtx-5
 63:      36892      78273      78853      27126      78559      55956      68976     107141   PCI-MSI-edge      ens192-rxtx-6
 64:       3027       6627       7506       6994      12081      13225      14441      19625   PCI-MSI-edge      ens192-rxtx-7
 65:          0          0          0          0          0          0          0          0   PCI-MSI-edge      ens192-event-8
...

如果希望手动分配,则需要先关闭 irqbalance Daemon。

$ service irqbalance stop
$ echo 01 > /proc/irq/57/smp_affinity

但需要注意的是,在大部分场景中,irqbalance Daemon 提供的中断分配优化都是可以起到积极作用的。irqbalance 会自动收集系统数据来分析出使用模式,并依据系统负载状况将工作状态调整为以下两种模式:

  1. Performance mode:irqbalance 会将中断尽可能均匀地分发给各个 CPU 的 Core,以充分提升性能。
  2. Power-save mode:irqbalance 会将中断处理集中到第一个 CPU,保证其它空闲 CPU 的睡眠时间,降低能耗。

ethtool 操作指令

  1. 设置使用 TCPv4 4-tuple HASH 计算。
ethtool -n eth0 rx-flow-hash tcp4
  1. 设置使用 UDPv4 4-tuple HASH 计算。
ethtool -N eth0 rx-flow-hash udp4 sdfn
  1. 设置 RETA 使用 6 个 Queues 的负载均衡。
ethtool -x eth0
ethtool -X eth0 equal 6
  1. 设置开启 Flow director,并将 IPv4 2-tuple 重定向到 Queue0。
ethtool -K eth0 ntuple on
ethtool -N eth0 flow-type ip4 action 0
ethtool -n eth0 flow-type
  1. 设置开启 Flow director,并使用 flexbytes 特性将 TCPv4 dstPort 5001 重定向到 Queue7。
ethtool -K net2 ntuple on
ethtool -N net2 flow-type tcp4 vlan-etype 5001 action 7
ethtool -n eth0 flow-type

猜你喜欢

转载自blog.csdn.net/Jmilk/article/details/130055391
RSS
今日推荐