KMALLOC大小分配

时间:2012-09-24 15:42:02

标签: c linux memory linux-kernel

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

3 个答案:

答案 0 :(得分:11)

我的理解如下:内核正在处理系统的物理内存,只能在页面大小的块中使用;因此,当您调用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

答案 1 :(得分:5)

这完全取决于内核中使用的分配器。平板,竹节或斯洛伐克。 请参阅以下内核配置变量:

CONFIG_SLAB
CONFIG_SLUB
CONFIG_SLOB

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

SLAB分配器支持的最大kmalloc大小为32兆字节(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直接分配适合订单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。

答案 2 :(得分:2)

您可以在系统中看到kmalloc()使用的一些常用尺寸:

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)分配失败的示例。