为什么kmem_cache索引的顺序是这样的?
/*
* Conversion table for small slabs sizes / 8 to the index in the
* kmalloc array. This is necessary for slabs < 192 since we have non power
* of two cache sizes there. The size of larger slabs can be determined using
* fls.
*/
u8 kmalloc_size_index[24] __ro_after_init = {
3, /* 8 */
4, /* 16 */
5, /* 24 */
5, /* 32 */
6, /* 40 */
6, /* 48 */
6, /* 56 */
6, /* 64 */
1, /* 72 */
1, /* 80 */
1, /* 88 */
1, /* 96 */
7, /* 104 */
7, /* 112 */
7, /* 120 */
7, /* 128 */
2, /* 136 */
2, /* 144 */
2, /* 152 */
2, /* 160 */
2, /* 168 */
2, /* 176 */
2, /* 184 */
2 /* 192 */
};
为什么不使用更符合人类预期的索引顺序?我的意思是为什么索引中的值在 [1, 7] 中不是连续的?例如。为什么 [8, 16) 字节大小的索引是 3 而不是 1?
9e5e8deca746 的原始提交没有提供该信息。
这里的虚假分享似乎并不是什么问题。除此之外,原始提交对描述为什么选择该元素顺序没有帮助。 LKML 也没有对此进行讨论:https://lore.kernel.org/lkml/[email protected]/ .
数组表
kmalloc_size_index
实际上映射到kmem缓存,并且大小不断增加。
问题是映射是间接,通过 kmem 缓存数组中的索引。并且该数组中的第一个元素不按大小排序:
const struct kmalloc_info_struct kmalloc_info[] __initconst = {
INIT_KMALLOC_INFO(0, 0),
INIT_KMALLOC_INFO(96, 96),
INIT_KMALLOC_INFO(192, 192),
INIT_KMALLOC_INFO(8, 8),
INIT_KMALLOC_INFO(16, 16),
INIT_KMALLOC_INFO(32, 32),
INIT_KMALLOC_INFO(64, 64),
INIT_KMALLOC_INFO(128, 128),
INIT_KMALLOC_INFO(256, 256),
...
};
如果您在
kmalloc_info
数组中以递增的大小排列索引,您会得到:
INIT_KMALLOC_INFO(0, 0)
INIT_KMALLOC_INFO(8, 8)
INIT_KMALLOC_INFO(16, 16)
INIT_KMALLOC_INFO(32, 32)
INIT_KMALLOC_INFO(64, 64)
INIT_KMALLOC_INFO(96, 96)
INIT_KMALLOC_INFO(128, 128)
INIT_KMALLOC_INFO(192, 192)
INIT_KMALLOC_INFO(256, 256)
正如您所发现的,
kmalloc_size_index
表中引用的索引具有相同的顺序,即它们对应于大小不断增加的缓存。