目录
概述
创建slab缓存,分配对象的实例,kmem_cache_create( )函数创建一个slab新缓存
struct kmem_cache * kmem_cache_create (const char *name, size_t size, size_t align, unsigned long flags, void (*ctor)(void *))
name
:缓存名称,proc文件系统(在/proc/slabinfo中)标识一个缓存。size
:缓存创建的对象的大小,它是以字节为单位。align
:每个对象的对齐方式。flags
:分配缓存时的选项;ctor
:一个可选的对象构造器,构造器是用户提供的回调函数。当从缓存中分配新对象时,可以通过构造器进行初始化。
实验
为studentA分配内存空间,先创建缓存cache,再分配obj。通过命令行查看slab对应的信息
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/mm.h>
static struct kmem_cache* slab_test;
struct student{
int age;
int score;
};
struct student* studentA;
static int num=0;
static void mystruct_constructor(void *addr)
{
memset(addr, 0, sizeof(struct student));
printk(KERN_DEBUG"alloc mem cache num=%d\n",num++);
}
int slab_test_create_kmem(void)
{
int ret = -1;
//alloc cache
slab_test = kmem_cache_create("slab_test", sizeof(struct student), 0, 0, mystruct_constructor);
if(slab_test != NULL){
printk("slub_test create success!\n");
ret=0;
}
//alloc obj
studentA = kmem_cache_alloc(slab_test, GFP_KERNEL);
if(studentA != NULL){
printk("alloc object success!\n");
ret = 0;
}
return ret;
}
static int __init slab_test_init(void)
{
int ret;
printk("slab_test kernel module init\n");
ret = slab_test_create_kmem();
return 0;
}
static void __exit slab_test_exit(void)
{
printk("slab_test kernel module exit\n");
kmem_cache_destroy(slab_test);
}
MODULE_LICENSE("GPL");
module_init(slab_test_init);
module_exit(slab_test_exit);
首先编译模块,执行命令insmod slab.ko插入模块,然后执行命令dmesg
dmesg 查看日志信息
[67668.244654] slab_test kernel module init
[67668.244689] slub_test create success!
[67668.244691] alloc mem cache num=0
[67668.244692] alloc mem cache num=1
[67668.244692] alloc mem cache num=2
...
[67668.244917] alloc mem cache num=253
[67668.244918] alloc mem cache num=254
[67668.244918] alloc mem cache num=255
[67668.244919] alloc object success!
解析
回调函数 mystruct_constructor被调用256次 ,这是因为当从缓存中分配新对象时就要调用一次。在下面分析中可以看到分配的obj数量。
综述:
- slab从buddy分配一个order为0的内存(一页),把这一页命名为slab_test,
- 把这一页分成很多小的object的,使用的时候就从slab中获取一个object
- 用完归还给slab管理。
此外还可以通过/sys/kernel/slab/slab_test 查看属性
root@ubuntu:/sys/kernel/slab/slab_test# ls
aliases cpu_partial free_calls object_size partial remote_node_defrag_ratio slabs_cpu_partial trace
align cpu_slabs hwcache_align objects_partial poison sanity_checks slab_size usersize
alloc_calls ctor min_partial objs_per_slab reclaim_account shrink store_user validate
cache_dma destroy_by_rcu objects order red_zone slabs total_objects
root@ubuntu:/sys/kernel/slab/slab_test# cat object_size
8
root@ubuntu:/sys/kernel/slab/slab_test# cat slab_size
16
root@ubuntu:/sys/kernel/slab/slab_test# cat objs_per_slab
256
root@ubuntu:/sys/kernel/slab/slab_test# cat order
0
参考
Linux内核API kmem_cache_create|极客笔记