![NAPI 与自适应中断](https://linux22.com/image/541148/NAPI%20%E4%B8%8E%E8%87%AA%E9%80%82%E5%BA%94%E4%B8%AD%E6%96%AD.png)
有人能解释一下如何使用以下两种技术来减轻高网络负载下的中断开销吗?
- Adaptive-rx/Adaptive-tx,以及
- 奈帕尼;
我希望得到一个更接近 Linux 内核源代码级别的解释差异的答案?另外,我想了解如何在负载约为 400Mbps 时强制 NIC 进入轮询/中断合并模式。
更多背景:
问题似乎是 bnx2 和 e1000 驱动程序忽略了“ethtool -C adapted-rx on”命令。这可能是因为这些驱动程序不支持自适应中断。尽管 Broadcom 程序员参考手册说此功能应该由 BCM5709 NIC 硬件支持。
因此,我决定尝试 NAPI,将 netif_napi_add() 函数调用中的权重从 64 减少到 16,以在负载低得多的情况下强制 NIC 处于轮询模式,但不幸的是,这没有奏效。我猜 NAPI 不需要 NIC 中的任何特殊硬件支持,对吗?
我使用的硬件是 BCM5709 NIC(它使用 bnx2 驱动程序)。操作系统是 Ubuntu 10.04。CPU 是 XEON 5620。
答案1
中断调节的主要原理是每接收一帧生成少于一个中断(或每完成一传输帧生成一个中断),从而减少处理中断时遇到的操作系统开销。BCM5709 控制器支持硬件中的几种中断合并方法,包括:
- 收到 X 帧(ethtool 中的 rx-frames)后产生中断
- 如果在 X 微秒后没有收到更多帧,则生成中断(ethtool 中的 rx-usecs)
使用这些硬件方法的问题是,您需要选择它们来优化吞吐量或延迟,而不能同时兼顾两者。为每个接收的帧生成一个中断(rx-frames = 1)可以最大限度地减少延迟,但这样做的代价是中断服务开销较高。设置较大的值(例如 rx-frames = 10)可以减少每十个接收帧仅生成一个中断所消耗的 CPU 周期数,但您也会遇到该十个帧中前几帧的延迟较高。
NAPI 实现试图利用流量成群出现的事实,这样您就可以在收到第一帧时立即生成中断,然后立即切换到轮询模式(即禁用中断),因为后面会有更多的流量。轮询一定数量的帧(您的问题中是 16 或 64)或某个时间间隔后,驱动程序将重新启用中断并重新开始。
如果您的工作负载可预测,则可以为上述任何一项(NAPI、rx-frames、rx-usecs)选择固定值,以便为您提供正确的权衡,但大多数工作负载都会有所不同,最终您需要做出一些牺牲。这就是自适应 rx/自适应 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?等)对延迟的敏感度。
戴夫