NAPI 与自适应中断

use*_*238 12 nic linux-networking

谁能解释一下如何使用以下两种技术来减轻高网络负载下的中断开销?

  1. 自适应接收/自适应发送,和
  2. NAPI;

我希望能解释更接近 linux 内核源代码级别的差异的答案?我也想听听如何在负载为 ~ 400Mbps 时强制 NIC 进入轮询/中断合并模式。

更多背景:

问题似乎是 bnx2 和 e1000 驱动程序忽略了“ethtool -Cadaptive-rx on”命令。这可能是因为这些驱动程序不支持自适应中断。尽管 Broadcom Programmer 的参考手册说 BCM5709 NIC 硬件应该支持此功能。

所以我决定尝试 NAPI 并在 netif_napi_add() 函数调用中将权重从 64 减少到 16,以在低得多的负载下强制 NIC 处于轮询模式,但不幸的是,这并没有奏效。我猜 NAPI 在 NIC 中不需要任何特殊的硬件支持,对吗?

我使用的硬件是 BCM5709 NIC(它使用 bnx2 驱动程序)。操作系统是 Ubuntu 10.04。CPU是至强5620。

小智 18

中断调节背后的主要原则是每个接收帧生成少于一个中断(或每个传输帧完成一个中断),从而减少服务中断时遇到的操作系统开销。BCM5709 控制器在硬件中支持多种合并中断的方法,包括:

  • 收到X帧后产生中断(ethtool中的rx-frames)
  • X usecs(ethtool 中的 rx-usecs)后不再接收帧时产生中断

使用这些硬件方法的问题在于您需要选择它们来优化吞吐量或延迟,您不能同时拥有。为每个接收到的帧(rx-frames = 1)生成一个中断可以最大限度地减少延迟,但就中断服务开销而言,这样做的成本很高。设置一个更大的值(比如 rx-frames = 10)会减少 CPU 周期的消耗,因为每接收到 10 帧就产生一个中断,但是对于这 10 帧中的第一帧,你也会遇到更高的延迟。

NAPI 实现试图利用流量成束的事实,以便您在接收到的第一帧时立即生成中断,然后您立即切换到轮询模式(即禁用中断),因为更多的流量将紧随其后。在您轮询一定数量的帧(问题中为 16 或 64)或某个时间间隔后,驱动程序将重新启用中断并重新开始。

如果您有一个可预测的工作负载,那么可以为上述任何一个(NAPI、rx-frames、rx-usecs)选择固定值,这会给您正确的权衡,但大多数工作负载各不相同,您最终会做出一些牺牲。这就是adaptive-rx/adaptive-tx 发挥作用的地方。那里的想法是驱动程序不断监视工作负载(每秒接收的帧数、帧大小等)并调整硬件中断合并方案以优化低流量情况下的延迟或优化高流量情况下的吞吐量。这是一个很酷的理论,但在实践中可能难以实施。只有少数驱动程序实现了它(请参阅http://fxr.watson.org/fxr/search?v=linux-2.6&string=use_adaptive_rx_coalesce)并且 bnx2/e1000 驱动程序不在该列表中。

有关每个 ethtool 合并字段应该如何工作的良好描述,请查看以下地址中 ethtool_coalesce 结构的定义:

http://fxr.watson.org/fxr/source/include/linux/ethtool.h?v=linux-2.6#L111

对于您的特定情况(~400Mb/s 吞吐量),我建议调整 rx-frames 和 rx-usecs 值以获得适合您工作负载的最佳设置。查看 ISR 的开销以及您的应用程序(httpd?等)对延迟的敏感性。

戴夫