在内核中高效分配内存

ker*_*der 4 c linux-kernel

我想编写一个内核模块,在那里我获得接近 8 mbps 的 TCP/IP 数据包。我必须将这些数据包存储 500 毫秒的持续时间。稍后这些数据包应按顺序转发。这些应该为 30 名成员完成。什么应该是最好的实施方法?我应该使用kmalloc一次(kmalloc(64000000, GFP_ATOMIC)吗?因为每次如果我这样做kmallockfree都需要时间,从而导致性能问题。另外,如果我一次性在内核中分配内存,Linux 内核会允许我这样做吗?

cor*_*rny 6

我曾经写过一个内核模块处理 10Gbs 链路上的数据包。我曾经vmalloc分配了大约 1GByte 的连续(虚拟)内存,将一个静态大小的哈希表放入其中以执行连接跟踪(代码)。

如果您知道需要多少内存,我建议您预先分配它。这有两个好处

  • 它很快(在运行时没有 mallocing/freeing)
  • 如果kmalloc(_, GFP_ATOMIC)不能恢复你的记忆,你不必考虑策略。这实际上可以在重负载下经常发生。

坏处

  • 您可能会在必要时分配更多内存。

因此,要编写专用内核模块,请预先分配尽可能多的内存;)

如果您为许多新手用户使用的商品硬件编写内核模块,那么按需分配内存(并浪费更少的内存)会很好。


你在哪里分配内存?GFP_ATOMIC只能返回非常少量的内存,并且只能在您的内存分配无法休眠时使用。您可以GFP_KERNEL在安全睡眠时使用,例如,不在中断上下文中。请参阅此问题了解更多信息。vmalloc在模块初始化期间使用预分配所有内存是安全的。

  • +1 代码。由于该代码使用二舍五入,请参阅 http://stackoverflow.com/questions/4398711/round-to-the-nearest-power-of-two - 内核具有 `ffs()` ,参见`<linux/bitops.h>`。 (2认同)