> 文档中心 > linux内核源码分析之slab(四)

linux内核源码分析之slab(四)

目录

概述

实验

解析  


概述

        创建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 #include #include #include 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数量。

综述:

  1. slab从buddy分配一个order为0的内存(一页),把这一页命名为slab_test,
  2. 把这一页分成很多小的object的,使用的时候就从slab中获取一个object
  3. 用完归还给slab管理。 

此外还可以通过/sys/kernel/slab/slab_test 查看属性

root@ubuntu:/sys/kernel/slab/slab_test# lsaliases      cpu_partial     free_calls     object_size      partial   remote_node_defrag_ratio  slabs_cpu_partial  tracealign cpu_slabshwcache_align  objects_partial  poison    sanity_checks      slab_size   usersizealloc_calls  ctor     min_partial    objs_per_slab    reclaim_account  shrink      store_user  validatecache_dma    destroy_by_rcu  objects order     red_zone  slabstotal_objectsroot@ubuntu:/sys/kernel/slab/slab_test# cat object_size 8root@ubuntu:/sys/kernel/slab/slab_test# cat slab_size 16root@ubuntu:/sys/kernel/slab/slab_test# cat objs_per_slab 256root@ubuntu:/sys/kernel/slab/slab_test# cat order 0

参考

深入理解Linux slab分配器 - 知乎

Linux内核API kmem_cache_create|极客笔记

https://course.0voice.com/v1/course/intro?courseId=2&agentId=0