【问题标题】:Can the Rx/Tx Packet Buffer size be changed dynamically on a Linux NIC driver?可以在 Linux NIC 驱动程序上动态更改 Rx/Tx 数据包缓冲区大小吗?
【发布时间】:2016-03-03 21:16:40
【问题描述】:

目前,发送和接收数据包大小由宏定义

#define PKT_BUF_SZ          (VLAN_ETH_FRAME_LEN + NET_IP_ALIGN + 4)

所以 PKT_BUF_SZ 大约为 1524 字节。因此,我拥有的 NIC 可以处理来自网络的小于等于 1524 的传入数据包。任何大于此值的数据都会导致系统崩溃或更严重的重新启动。使用 Linux 内核 2.6.32 和 RHEL 6.0,以及定制的 FPGA NIC。

有没有办法通过从 NIC 获取传入数据包的大小来动态更改 PKY_BUF_SZ?它会增加开销吗?硬件是否应该在数据包到达驱动程序之前将其丢弃?

任何帮助/建议将不胜感激。

【问题讨论】:

  • 自从我上次研究 NIC 驱动程序以来已经有一段时间了,但是典型的 NIC 曾经有一个 固定 预分配缓冲区池,通常排列为环形列表.当发生数据包泛滥时,没有时间允许根据大小动态分配缓冲区。在帧完全存储在 RAM 中之前,主机 CPU 甚至不参与数据包接收。所以这实际上是一个需要固定缓冲区大小的硬件限制。
  • 是的,这是有道理的。任何通过线路的巨型数据包帧都会被硬件丢弃。但是如果我们放宽这个特性,那么一些数据包就会偷偷溜进来。但是如果缓冲区大小小于传入的数据包,它会导致崩溃/重启。就像非法访问内存一样?
  • “但是如果我们放宽这个功能,那么......” -- 你在规定什么愚蠢的场景?检查您正在使用的以太网控制器的数据表和/或驱动程序。也许它支持巨型帧,通常使用多个缓冲区(也称为碎片)。
  • 我的错,它确实支持你提到的巨型帧。如果协议未设置为接收巨型数据包。我的驱动程序必须丢弃数据包还是将其发送到协议层并让协议处理它?我的问题是,当 NIC 接收到大于 MTU 大小(1524 字节)的数据包时,系统会重新启动。例如,正在接收大小为 1800 字节的数据包。是因为我的环形缓冲区耗尽了吗?再次感谢您的建议。驱动程序代码中没有处理巨型 MTU 的工具。我可能需要添加该功能。

标签: linux-kernel network-programming linux-device-driver


【解决方案1】:

这不是在不了解特定控制器的情况下可以回答的问题。它们在细节上的工作方式都不同。

例如,一些 Broadcom NIC 具有不同大小的缓冲区池,控制器将根据帧大小从中选择一个合适的缓冲区。例如,一个小(256)字节缓冲区池、一个标准大小(1536 左右)缓冲区池和一个巨型缓冲区池。

一些英特尔 NIC 允许列出固定大小的缓冲区以及最大帧大小,然后它会根据需要拉取尽可能多的连续缓冲区(虽然不确定 linux 是否支持这种用途——软件处理起来要复杂得多)。

但大多数 NIC 使用的最常见模型(事实上,我相信所有商业的 都可以以这种方式使用):他们希望整个帧适合单个缓冲区,并且您的单个缓冲区大小需要容纳您将收到的最大帧。

鉴于您的 NIC 是定制的 FPGA,只有其设计人员才能就您所要求的细节向您提供建议。如果 linux 在更大的数据包通过时崩溃,那么很可能您分配的缓冲区大小没有您告诉 NIC 的那么大(导致溢出),或者 NIC 有一个错误导致它写入一些其他内存区域。

【讨论】:

  • Cheers Gil,我想你已经涵盖了所有可能的场景。在最后一段中,您可能已经向我提供了我正在寻找的答案。必须决定 NIC 是否要支持超大缓冲区,然后在软件中进行必要的更改。需要与硬件工程师取得联系,让他帮助我解决这个问题。此外,将标准缓冲区大小增加到 1600,以便它容纳大约 1536 字节的标准大小的数据包。
猜你喜欢
  • 1970-01-01
  • 2014-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-15
  • 1970-01-01
相关资源
最近更新 更多