NetXtreme II BCM5709 千兆以太网 NIC 支持 MSI 功能(消息信号中断),它有 8 个队列。每个队列在 /proc/interrupts 中都有自己的中断处理程序。我试图完成的是告诉 NIC 哪些数据包应该进入哪个队列。
问题:
- 是否可以通过封装的协议类型手动指定哪些 IP 数据包应该进入哪个队列(例如 IPsec 数据包进入一个队列,而 TCP 数据包进入另一个队列)?
- 如果可能的话--我该如何在Linux下做到这一点?
- 如果不可能的话——我是否应该考虑使用支持 MSI-X 的 NIC 卡来解决这个问题?
更多细节:
我们有一个接口正在终止 IPSec 并转发/终止 TCP 连接。IPSec 数据包解密是内联的(这意味着解密是在相同的 ksoftirqd/X 上下文下完成的)。我们试图找出如果 IPSec 数据包将在另一个 CPU 上而不是 TCP 数据包上调度,我们是否能够提高总体性能。另一个限制是 IPSec 代码不是 MP 安全的,因此我无法在多个 ksoftirqd/X 下运行它。默认情况下,数据包似乎是通过源 IP 在 8 个 NIC 队列上分发/散列的。瓶颈是 IPSec,它在 ksoftirqd/X 上下文下以大约 100% 的 CPU 解密/加密 IPSec 数据包时会扼杀 TCP 流量。
操作系统是 Ubuntu 10.10(2.6.32-27-server),网卡是 Broadcom BCM5709。
答案1
如果其他人试图找出如何使 Linux 网络 TCP/IP 堆栈在多个 CPU 核心上扩展……
MSI 可被两种底层 NIC 技术利用,将数据包分发到多个队列中。每个 NIC 队列由专用 CPU 核心上的不同中断处理,以实现可扩展性:
- RSS(接收方缩放)- 根据源和目标 IP 以及(如果适用)TCP/UDP 源和目标端口将数据包分发到不同的队列。
- VMDq(虚拟机设备队列)- 通过 MAC 地址或 VLAN 标签分发数据包。主要用于 VM 虚拟机管理程序,但我看不出它不能用于非 VM 设置的任何理由。
RSS 的问题在于它总是使用源 IP 来生成哈希值。哈希值用于查找此数据包应进入哪个队列。这意味着,除非用户还能控制源 IP,否则无法控制哪些数据包应进入哪个队列。
VMDq 似乎更适合我的问题,因为它根据目标 MAC 地址分发数据包。它可以像为同一接口分配两个不同的 IP 地址一样简单。
来源: