kmem_cache_create函数功能描述:kmem_cache_create( )函数用来创建一个slab新缓存,这通常是在内核初始化时执行的,或者在首次加载内核模块时执行。
kmem_cache_create文件包含
#include
kmem_cache_create函数定义
在内核源码中的位置:linux-3.19.3/mm/slab_common.c
函数定义格式:
struct kmem_cache * kmem_cache_create (const char *name, size_t size, size_t align, unsigned long flags, void (*ctor)(void *))
kmem_cache_create输入参数说明
name
:该参数指缓存名称,proc文件系统(在/proc/slabinfo中)使用它标识一个缓存。size
:该参数指定了为这个缓存创建的对象的大小,它是以字节为单位的。align
:该参数定义了每个对象的对齐方式。flags
:该参数指定了分配缓存时的选项,这些选项标志如表所示。
ctor
:参数定义了一个可选的对象构造器,构造器是用户提供的回调函数。当从缓存中分配新对象时,可以通过构造器进行初始化。
kmem_cache_create返回参数说明
struct kmem_cache是对slab缓存进行描述的数据结构,kmem_cache_create( )函数返回一个该结构类型指针。其中kmem_cache结构包含了每个中央处理器单元(CPU)的数据、一组可调整的(可以通过proc文件系统访问)参数、统计信息和管理slab缓存所必需的元素。
其中结构体kmem_cache在文件linux-3.19.3/include/linux/slab_def.h中定义,这里给出了部分字段的注释:
struct kmem_cache {
struct array_cache __percpu * cpu_cache;
/*每个CPU指针数组指向包含空闲对象的本地告诉缓存*/
unsigned int batchcount; /*要转移进本地高速缓存或从本地高速缓存中转移出的大批对象的数量*/
unsigned int limit; /*本地高速缓存空闲对象的最大数目。这是可调的*/
unsigned int shared;
unsigned int size;
struct reciprocal_value reciprocal_buffer_size;
unsigned int flags; /*描述高速缓存永久属性的一组标志*/
unsigned int num; /*封装在一个单独slab中的对象个数*/
unsigned int gfporder; /*一个单独slab中包含的连续页框数目的对数*/
gfp_t gfpflags; /*分配页框时传递给伙伴系统函数的一组标志*/
size_t colour; /*slab使用的颜色个数*/
unsigned int colour_off; /*slab中的基本对齐偏移*/
struct kmem_cache *freelist_cache; /*freelist缓冲区链表*/
unsigned int freelist_size; /*freelist的大小*/
void (*ctor)(void *obj); /*指向与高速缓存相关的构造方法的指针*/
const char *name; /*存放高速缓存名字的字符数组*/
struct list_head list; /*高速缓存描述符双向链表使用的指针*/
……
};
kmem_cache_create实例解析
编写测试文件:kmem_cache_create.c
头文件及全局变量声明如下:
#include
#include
#include
MODULE_LICENSE("GPL");
static int __init kmem_cache_create_init(void);
static void __exit kmem_cache_create_exit(void);
char * mem_spvm = NULL;
struct kmem_cache *my_cachep = NULL;
模块初始化函数:
int __init kmem_cache_create_init(void)
{
my_cachep = kmem_cache_create("my_cache",32,0, SLAB_HWCACHE_ALIGN, NULL);
if(my_cachep == NULL )
printk("kmem_cache_create failed! \n");
else
{
printk("Cache size is: %d\n", kmem_cache_size(my_cachep));
}
return 0;
}
模块退出函数:
void __exit kmem_cache_create_exit(void)
{
if(my_cachep)
{
kmem_cache_destroy(my_cachep);
printk("kmem_cache_destroy succeed! \n");
}
printk("exit! \n");
}
模块初始化及退出函数调用:
module_init(kmem_cache_create_init);
module_exit(kmem_cache_create_exit);
实例运行结果及分析:
首先编译模块,执行命令insmod kmem_cache_create.ko插入模块,然后执行命令dmesg -c,会出现如图所示的结果。
执行命令rmmod kmem_cache_create.ko卸载模块,执行命令dmesg -c,会出现如图所示的结果。
结果分析:
该测试文件调用kmem_cache_create( )函数创建了一个新slab缓存,命名为“my_cache”,同时将缓存对象大小设置为32字节,并指定缓存对象必须与硬件缓存对齐。my_cache为描述该新缓存的结构指针。kmem_cache_size( )函数返回该缓存所管理的对象的大小,kmem_cache_name( )函数用来检索缓存名称,调用两个函数来测试创建的缓存。从输出信息可以看出新创建的缓存kmem_cache的对象的大小为32字节,名称为“kmalloc_32”,这里需要注意的是kmem_cache_name( )不保证返回与创建时给定的常量名相同的指针,需要程序自己处理。最后在模块退出时调用kmem_cache_destroy( )销毁新创建的slab缓存,参考极客笔记网该函数的分析。