OPNsense调整网卡RSS参数提升网络性能

时间:2023-02-02 16:00:15

RSS用于使用散列函数在 CPU 内核上分发数据包——为卸载散列的硬件或软件提供支持。启用接收方缩放 (RSS) 时,特定TCP连接的所有接收数据处理都在多个处理器或处理器内核之间共享。如果没有 RSS,所有处理都由单个处理器执行,导致系统缓存利用率低下,影响网络的吞吐量。

注意:为提升硬件的兼容性,默认情况下在OPNsense中RSS被禁用。

网卡/驱动

如果驱动程序支持启用/禁用 RSS选项,则可以使用sysctl可调参数来设置。

查看是否启用或禁用RSS,可以执行以下命令:

sysctl -a | grep rss

这会显示任何通过可调参数公开该选项的驱动程序。

也有可能驱动程序没有向用户公开此功能,在这种情况下,需要使用在线数据表或谷歌搜索来查找NIC/驱动程序是否完全支持 RSS。例如,igb默认启用 RSS,dut不会在任何配置参数中反映这一点。但是,由于它使用多个队列:

# dmesg | grep vectors

igb0: Using MSI-X interrupts with 5 vectors
igb1: Using MSI-X interrupts with 5 vectors
igb2: Using MSI-X interrupts with 5 vectors
igb3: Using MSI-X interrupts with 5 vectors

很可能有某种形式的数据包过滤来在硬件队列上分发数据包。事实上,igb默认会做RSS。

RSS内核实现必须有驱动程序的支持。合适的驱动程序支持将确保在硬件中设置正确的密钥和间接表。以下是各种NIC驱动程序支持情况(大部分未经测试):

  • em
  • igb -> 已测试可以正常工作
  • axgbe -> 已测试可以正常工作
  • netvsc
  • ixgbe
  • ixl
  • cxgbe
  • lio
  • mlx5
  • sfxge

内核支持

在内部,FreeBSD使用​​netisr​​ 作为抽象层来将数据包分派给上层协议。在实现中,默认设置是将数据包处理限制为仅一个线程。由于RSS现在提供了一种将流保持在CPU 本地的方法,因此可以在系统->设置>可调参数中调整以下选项的值:

net.isr.bindthreads = 1
net.isr.maxthreads = -1

第一个选项设置一个线程绑定到一个 CPU,下面一个选项为每个可用的核心分配一个工作流。

要启用RSS,必须将以下参数修改为1:

net.inet.rss.enabled = 1

默认情况下该参数为0,禁用RSS,以防止出现未知的问题。

net.inet.rss.bits = X

取决于CPU拥有的内核数量。默认情况下,此处的位数表示内核数 x 2(二进制)。这样做是为了提供负载平衡,但目前还没有实现,因此我们建议将此值设置为表示CPU内核数的位数。

  • 4核系统,使用“2”
  • 8核系统,使用“3”
  • 16核系统,使用“4”
  • 等等。

修改后重新启动防火墙。

测试

启用RSS后,数据包分发策略将从“直接”变为“混合”。将在允许的情况下直接在当前上下文中发送数据包,否则它将在数据包所在的绑定CPU上排队。注意会增加中断负载,如“top -P”所示。这只是意味着数据包在CPU调度程序中以最高优先级进行处理——这并不意味着CPU的负载比正常情况下高。

netisr 的正确工作可以通过运行以下命令来验证:

netstat -Q

经群内网友测试,在启用RSS后,并调整kern.ipc.maxsockbuf参数的值后,cx341a网卡转发可以跑满万兆。

未启用RSS测试数据:

OPNsense调整网卡RSS参数提升网络性能

启用RSS后测试数据:

OPNsense调整网卡RSS参数提升网络性能

注意事项

当Suricata在IPS模式下运行时,Netmap用于从线上获取数据包来供检查。默认情况下,OPNsense已将Suricata配置为将通过检查的数据包重新注入主机网络堆栈以用于路由/防火墙目的。当前的Suricata/Netmap实现将这种重新注入仅限于一个线程。解决此问题的工作正在进行中,因为新的Netmap API (V14+) 现在能够增加此线程数。在此之前,使用IPS时,启用RSS不会带来任何好处。

​原文地址​​。