kernel阅读手记之kmalloc

内核中,分别对于不同的应用层面,对 kmalloc 有不同的定义,分别位于

slab.c

Mark Hemment 捣鼓的,从从 Sun OS 引进

slob.c

针对嵌入式系统,主要是针对内存非常有限的设备

slub.c

可以说是对 slab 的重新设计,代码量更下,并且能够更好的适应 large NUMA 系统 , 被认为时 slab slob 的取代者

 

 

Slob 中的 kmalloc 只有一个语句, return __kmalloc_node(size, flags, -1); 跟踪相应的 __kmalloc_node() 函数,该函数首先会获得 ARCH_KMALLOC_MINALIGN ARCH_SLAB_MINALIGN 中的 max 值,当需要分配的页面大小小于 PAGE_SIZE 减去 max 的差时:

1、  size 0 时,返回 ZERO_SIZE_PTR 错误

2、  采用 slob_alloc 分配内存,不成功时返回错误

3、  返回 size+max 的地址

否则,调用 slob_new_page 重新分配一个新的内存空间,并且将分配的虚地址转化成的物理地址交给一个 page->private 的值为所分配的大小的页面。

 

 

在看 Slub slab 中的 kmalloc 的时候先要了解 __builtin_constant_p 是一个 gcc 的内建函数用于判断一个值是否为编译时常数,如果参数 EXP 的值是常数,函数返回 1 ,否则返回 0

 

Slub 中,首先判断 kmalloc 函数中的 size 的类型,如果是在编译时不确定,那么直接调用 __kmalloc(size, flags) 并且取值返回,否则,将在返回之前 进行一些判断:

1、 当需分配的的大小大于页面大小时,使用 __kmalloc(size, flagkmalloc_larges) 进行分配

2、  当分配时带有 SLUB_DMA 标记时,首先采用 kmalloc_slab(size) 分配内存,分配失败时,返回 ZERO_SIZE_PTR

3、  返回 kmem_cache_alloc(s, flags)

__kmalloc(size, flags)

1、 size 不大于 PAGE_SIZE 时,调用 kmalloc_large(size, flags) 分配空间并返回

2、 get_slab(size, flags) 返回值不为 0 或者空时,返回其返回值

3、 调用 slab_alloc(s, flags, -1, __builtin_return_address(0)) 分配空间

 

kmalloc_large(size, flags) 调用 __get_free_pages(flags | __GFP_COMP, get_order(size)); 返回指定大小的空闲页面

 

kmalloc_slab() kmalloc_index(size) 返回的索引不为 0 时,调用 kmalloc_cache(index) 分配页面

 

kmem_cache_alloc() 返回 slab_alloc() 给分配的空间。

 

 

Slab 中的 kmalloc() 分配策略类似于 sulb 中,都需要对 size 的类型进行判断, 如果是在编译时不确定,那么直接调用 __kmalloc(size, flags) 并且取值返回,否则,将在返回之前进行一些判断:

1、 错误处理,当 size 0 时,返回 ZERO_SIZE_PTR

2、  cache 的值小于 size 时, i+=1, 否则跳到 found 处执行

如果在编译选项中设置了 CONFIG_ZONE_DMA ,并且标明了 GFP_DMA ,调用 kmem_cache_alloc(malloc_sizes[i].cs_dmacachep, flags) 分配内存并返回。否则调用 kmem_cache_alloc(malloc_sizes[i].cs_cachep, flags); 分配内存并返回

 

__kmalloc(size, flags)

返回 __do_kmalloc(size, flags, NULL); 的值

 

 

kmem_cache_alloc

返回 __cache_alloc(cachep, flags, __builtin_return_address(0)) 的值

 

__do_kmalloc()

得到一个 cache 的指针,如果指针不为空或者 0 的时候,返回指针,否则调用 __cache_alloc(cachep, flags, caller) 分配一个缓存并返回

 

__cache_alloc()

该函数主要功能是分配一个

1、         得到一个 CPU 的对应的 cache 数组,设置为变量 ac

2、         ac 可用时, cache 指针加 1 并且状态设置成命中 , 返回 ac 的入口指针

3、         或者将 cache 指针加 1 ,返回重新分配并填充的 cache 指针

你可能感兴趣的:(cache,gcc,OS,null,嵌入式,sun)