在start_kernel函数中将调用proc_caches_init()
用于为linux内核中内核对象初始化slab缓存描述符。该函数定义如下(/kernel/fork.c):
void __init proc_caches_init(void)
{
sighand_cachep = kmem_cache_create("sighand_cache",
sizeof(struct sighand_struct), 0,
SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_DESTROY_BY_RCU|
SLAB_NOTRACK, sighand_ctor);
signal_cachep = kmem_cache_create("signal_cache",
sizeof(struct signal_struct), 0,
SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL);
files_cachep = kmem_cache_create("files_cache",
sizeof(struct files_struct), 0,
SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL);
fs_cachep = kmem_cache_create("fs_cache",
sizeof(struct fs_struct), 0,
SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL);
mm_cachep = kmem_cache_create("mm_struct",
sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN,
SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL);
vm_area_cachep = KMEM_CACHE(vm_area_struct, SLAB_PANIC);
mmap_init();
nsproxy_cache_init();
}
在proc_caches_init的开头,会通过调用kmem_cache_create()
函数去分配不同的SLAB缓存:
sighand_cachep
— 管理有关已安装信号处理程序的信息。
signal_cachep
— 管理有关进程信号描述符的信息。
files_cachep
— 管理打开的文件信息。
fs_cachep
—管理文件系统信息。
对于以上四种slab缓存区域,linux内核中对其分配、创建 、释放过程分别如下所示:
(1)sighand_cachep缓存
(2)signal_cachep缓存
(3)files_cachep缓存
(4)fs_cachep缓存
在此之后,还将为mm_struct结构分配SLAB缓存,如下代码片段:
mm_cachep = kmem_cache_create("mm_struct",
sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN,
SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL);
linux内核中对mm_cachep
缓存空间的分配、创建 、释放过程如下所示:
接着,将为重要的vm_area_struct结构分配SLAB缓存,linux内核使用它来管理虚拟内存空间:
vm_area_cachep = KMEM_CACHE(vm_area_struct, SLAB_PANIC);
linux内核中对vm_area_cachep
缓存空间的分配、创建 、释放过程如下所示:
注意,这里使用的是KMEM_CACHE宏,而不是kmem_cache_create。这个宏在include/linux/slab.h中进行定义,只是展开本质为kmem_cache_create的调用,如下代码片段:
#define KMEM_CACHE(__struct, __flags) kmem_cache_create(#__struct,\
sizeof(struct __struct), __alignof__(struct __struct),\
(__flags), NULL)
KMEM_CACHE
与kmem_cache_create()
有一个区别。体现在__alignof__ *** 作符上,KMEM_CACHE宏将SLAB对齐到给定结构的大小,但是kmem_cache_create会使用给定的值来对齐空间。
接下来,proc_caches_init()
将调用mmap_init和nsproxy_cache_init这两个函数。第一个函数用于初始化虚拟内存区域的Slab,第二个函数用于初始化名称空间的slab。
对于proc_caches_init()
来说,其函数内核的实现是创建slab缓存描述符,包括:sighand_cachep、signal_cachep、files_cachep、fs_cachep、mm_cachep、vm_area_cachep等。
本文中一直出现slab这个关键词,slab是linux内核中的小内存分配器,对于linux内核来说,因为很多linux内核的对象不会使用内存页面分配的方式进行。故而会使用slab分配器来分配,在slab中分配小内存,首先要做的就是创建slab描述符,proc_caches_init()
函数的用意就在于此!
关于linux内核的slab分配器,其内容很多,笔者计划在后续linux内核的内存管理文章中进行分享啦,文本已完!
搜索关注【嵌入式小生】wx公众号获取更多精彩内容。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)