KMALLOC 大小分配

Posted

技术标签:

【中文标题】KMALLOC 大小分配【英文标题】:KMALLOC size allocation 【发布时间】:2012-09-24 15:42:02 【问题描述】:

KMALLOC 是只分配页面大小的内存还是可以分配更少的内存? kmalloc 可以分配的大小是多少? 我在哪里可以找到它的描述,因为我到处看它并没有真正说明它分配了多少内存? 我想知道 KMALLOC 分配的实际大小是多少。 它是否分配 2 的幂大小? 它只是从准备好的缓存中找到空闲对象吗?

【问题讨论】:

kmalloc() 的源代码可以为您提供所有这些信息。至于实际分配的内存量,请参见ksize() function。有时,kmalloc() 确实在适当的缓存中寻找一个空闲对象,有时它诉诸于分配整个页面。是的,kmalloc 可以分配实际大小小于一页的块。实现会随着时间而变化,因此分析kmalloc() 的源代码可能比查找任何其他文档更有用。 【参考方案1】:

我的理解是这样的:内核是在处理系统的物理内存,只有page-sized chunks才有;因此,当您调用kmalloc() 时,您只会得到某些预定义的、固定大小的字节数组。

实际取回的内存取决于系统的体系结构,但 kmalloc 可以处理的最小分配是 32 或 64 字节。您会从kmalloc() 的电话中得到回复至少与您要求的内存一样多(通常更多)。通常不会超过 128 KB(同样,取决于架构)

要获取系统的页面大小(以字节为单位),您可以执行以下命令:

getconf PAGESIZE

getconf PAGE_SIZE

有关最大页面大小的信息位于 /usr/src/linux/include/linux/slab.h

是的,页面大小通常是 2 的幂,但同样,您不会得到您想要的,而是更多。

您可以使用如下代码:

void * stuff;
stuff = kmalloc(1,GFP_KERNEL);
printk("I got: %zu bytes of memory\n", ksize(stuff));
kfree(stuff);

显示实际分配的内存量:

[90144.702588] I got: 32 bytes of memory

【讨论】:

【参考方案2】:

这完全取决于内核中使用的分配器。板坯、竹节或粗杆。 请参阅以下内核配置变量:

CONFIG_SLAB
CONFIG_SLUB
CONFIG_SLOB

以上所有分配器都使用 MAX_ORDERPAGE_SHIFT 来决定 kmalloc() 的最大限制

SLAB 分配器支持的最大 kmalloc 大小为 32 MB (2^25) 或最大可分配页顺序(如果小于 32 MB)。

#define KMALLOC_SHIFT_HIGH      ((MAX_ORDER + PAGE_SHIFT - 1) <= 25 ? \
  (MAX_ORDER + PAGE_SHIFT - 1) : 25)
#define KMALLOC_SHIFT_MAX       KMALLOC_SHIFT_HIGH

SLUB 直接将请求分配到 order-1 页面 (PAGE_SIZE*2)。更大的请求被传递给页面分配器。

#define KMALLOC_SHIFT_HIGH      (PAGE_SHIFT + 1)
#define KMALLOC_SHIFT_MAX       (MAX_ORDER + PAGE_SHIFT)

SLOB 将所有大于一页的请求传递给页面分配器。不需要 kmalloc 数组,因为可以从同一页面分配不同大小的对象。

#define KMALLOC_SHIFT_HIGH      PAGE_SHIFT
#define KMALLOC_SHIFT_MAX       30

kmalloc() 可分配的最大大小为

#define KMALLOC_MAX_SIZE        (1UL << KMALLOC_SHIFT_MAX)

kmalloc() 可分配的最小大小为

#define KMALLOC_MIN_SIZE (1 << KMALLOC_SHIFT_LOW)

slab 的默认 KMALLOC_SHIFT_LOW 为 5,而 slub 和 slob 的默认值为 3。

【讨论】:

【参考方案3】:

您可以通过以下方式查看kmalloc() int 您的系统使用的一些常用尺寸:

cat /proc/slabinfo  | grep kmalloc

比考虑 kmalloc 是否可以分配少于一页更重要的是它是否可以分配多于一页的问题:如果您在原子上下文中调用 kmalloc()(带有 GFP_ATOMIC 标志),它不能也不会非常努力地在内存中寻找连续的页面,所以如果你的内存非常碎片化,并且你的分配顺序很高(allocation size → pagesize*2^(allocation order)),分配可能会失败。因此,在原子上下文中,大分配可能会失败。

this other SO question about maximum AF_UNIX datagram size 有一个订单 7 (512 Kb) 分配失败的示例。

【讨论】:

以上是关于KMALLOC 大小分配的主要内容,如果未能解决你的问题,请参考以下文章

kmalloc函数详解

Linux设备驱动程序 之 kmalloc

RK3399平台开发系列讲解(内存篇)18.4kmalloc与vmalloc区别

Linux内核内存分配函数之kmalloc

第八章 分配内存

kmalloc 分配实际上不是连续的吗?