Linux内核快速处理路径尽量多用kmem_cache而慎用kmalloc

来源:www.zhonghengtong.com 发布时间:2020-06-27

标题是典型的《Effective C++++》风格。

问题是,让我给你一个大概的想法。

我正在开发一个Netfilter模块来匹配PREROUTING中的一些数据包。显然,每个人都可以将哈希表hlist作为数据结构的容器,它包含以下结构:

结构项{

结构hlist _ node hnode

填充字符[16];

};

在生成项目时,我首先使用kmalloc接口来分配内存:

item_nd=(结构项*)k local(结构项的大小,GFP _ KERNEL);

然后我使用添加/删除接口将分配的结构插入到列表中。

目的链表。

尽管这是一个恶意的遍历操作,但对于200个项目来说,一切都没问题,而且性能几乎是无损的,无论是吞吐量还是pps。

此时,我想扩展一些函数,从而向项目结构中添加一个字段:

结构项{

结构hlist _ node hnode

填充字符[16];

无效*私人;

};

Hlist,同样的遍历,吞吐量和pps下降到15% ~ 20%!

为什么添加指针变量会有如此大的性能差异?

事物的线索隐藏在kmalloc界面中!

事实是,当私有指针没有被添加时,项目结构的大小是32。添加指针时,大小变为40。不要低估这8个字节:

32字节大小所有200个项目在内存中几乎是连续的。

几乎所有40字节大小的200个项目在内存中都是不连续的。

为什么会这样?32和40有什么特别的吗?

我们将继续往下看。

kmalloc后面实际上是一系列kmem_cache:

8字节的Kmem_cache

16字节的Kmem_cache

32字节的Kmem_cache

64字节的Kmem_cache

92字节的Kmem_cache

128字节的Kmem_cache

.

我们可以从/proc/slabinfo中看到:

[root