kmem_cache_init
时间: 2024-04-08 13:06:21 浏览: 75
kmem_cache_init是Linux内核中用于初始化对象缓存的函数,它在内核启动时被调用,用于初始化对象缓存的数据结构和相关的数据结构。
具体来说,kmem_cache_init函数会先调用kmem_cache_create函数创建一个新的对象缓存,然后根据对象缓存的大小和架构特性,初始化对象缓存的各种属性和参数。内核会预先分配一部分内存用于对象缓存的管理,这些内存通常被称为slab,因此kmem_cache_init函数还会初始化slab的相关信息,比如slab的大小、数量和分配方式等等。
需要注意的是,kmem_cache_init函数只是用于初始化对象缓存的数据结构和相关的数据结构,它并不会分配对象缓存中的具体内存。具体的内存分配是在调用kmem_cache_alloc函数时进行的。
相关问题
void __init proc_caches_init(void) { sigact_cachep = kmem_cache_create("signal_act", sizeof(struct signal_struct), 0, SLAB_HWCACHE_ALIGN, NULL, NULL); if (!sigact_cachep) panic("Cannot create signal action SLAB cache"); files_cachep = kmem_cache_create("files_cache", sizeof(struct files_struct), 0, SLAB_HWCACHE_ALIGN, NULL, NULL); if (!files_cachep) panic("Cannot create files SLAB cache"); fs_cachep = kmem_cache_create("fs_cache", sizeof(struct fs_struct), 0, SLAB_HWCACHE_ALIGN, NULL, NULL); if (!fs_cachep) panic("Cannot create fs_struct SLAB cache"); vm_area_cachep = kmem_cache_create("vm_area_struct", sizeof(struct vm_area_struct), 0, SLAB_HWCACHE_ALIGN, NULL, NULL); if(!vm_area_cachep) panic("vma_init: Cannot alloc vm_area_struct SLAB cache"); mm_cachep = kmem_cache_create("mm_struct", sizeof(struct mm_struct), 0, SLAB_HWCACHE_ALIGN, NULL, NULL); if(!mm_cachep) panic("vma_init: Cannot alloc mm_struct SLAB cache"); }
这段代码是在内核初始化时创建了几个 SLAB 缓存,用于存放进程相关的数据结构。首先是创建一个名为 "signal_act" 的 kmem_cache,用于存放信号处理的数据结构 signal_struct。接着创建一个名为 "files_cache" 的 kmem_cache,用于存放进程文件信息的数据结构 files_struct。再创建一个名为 "fs_cache" 的 kmem_cache,用于存放进程文件系统信息的数据结构 fs_struct。然后,创建一个名为 "vm_area_struct" 的 kmem_cache,用于存放进程内存映射区域的数据结构 vm_area_struct。最后,创建一个名为 "mm_struct" 的 kmem_cache,用于存放进程地址空间的数据结构 mm_struct。如果在创建过程中出现错误,则会调用 panic 函数,使系统进入崩溃状态。
static inline int copy_sighand(unsigned long clone_flags, struct task_struct * tsk) { struct signal_struct *sig; if (clone_flags & CLONE_SIGHAND) { atomic_inc(¤t->sig->count); return 0; } sig = kmem_cache_alloc(sigact_cachep, GFP_KERNEL); tsk->sig = sig; if (!sig) return -1; spin_lock_init(&sig->siglock); atomic_set(&sig->count, 1); memcpy(tsk->sig->action, current->sig->action, sizeof(tsk->sig->action)); return 0; }
这段代码用于在进程间复制信号处理程序。如果 clone_flags 参数中包含 CLONE_SIGHAND 标志,则直接增加当前进程的信号计数器,并返回 0 表示复制成功。否则,需要为新进程分配一个 signal_struct 结构体,并将其指针赋值给新进程的 sig 成员变量。如果分配失败,则返回 -1 表示复制失败。然后,初始化新进程信号处理程序的互斥锁 siglock,将新进程信号计数器 count 的值设置为 1,并将当前进程信号处理程序的处理函数复制到新进程信号处理程序中。最后返回 0 表示复制成功。需要注意的是,在进程退出时,需要将信号处理程序的计数器 count 减 1,当计数器减到 0 时,才能释放相应的内存空间。
阅读全文