1. 前言
kmem_cache是Linux内核提供的快速内存缓冲接口,这些内存块要求是大小相同的,因为分配出的内
存在接口释放时并不真正释放,而是作为缓存保留,下一次请求分配时就可以直接使用,省去了各种
内存块初始化或释放的操作,因此分配速度很快,通常用于大数量的内存块分配的情况,如inode节
点,skbuff头, netfilter的连接等,其实kmalloc也是从kmem_cache中分配的,可通
过/proc/slabinfo文件直接读取cache分配情况。
以下Linux内核代码版本为2.6.19.2, 程序主要出自mm/slab.c文件, 2.4和2.6基本原理差不多,但具
体实现中有了不少变化。
2. slab和page
在介绍kmem_cache之前需要先介绍page和slab这两个定义。众所周知,page是内核中内存基本管理单
位,每个page的内存大小是固定的,对X86机器来说,是4K;slab则是kmem_cache的具体的内存空间
形式,根据cache的对象的大小,每个slab可以有1个page到最多32(128/4)个page;如果cache对象比
一个page的空间小,这个slab中会容纳多个对象以尽可能地利用空间。
struct slab {
// 链表
struct list_head list;
// 未用空间的偏移
unsigned long colouroff;
// 具体的内存缓冲区地址
void *s_mem; /* including colour offset */
// 每个slab中的正在使用的对象数量
unsigned int inuse; /* num of objs active in slab */
// 空闲对象
kmem_bufctl_t free;
unsigned short nodeid;
};
3. 数据结构
kmem_cache数据结构并没有定义在.h的头文件中,在头文件中只是该结构的一个类型定义,因为其他
地方使用kmem_cache时完全不需要知道其内部结构,各接口函数完全封装结构中的信息,这是用C实
现OO编程的常用方式。
/* include/linux/slab.h */
// 这里只是一个类型定义
typedef struct kmem_cache kmem_cache_t;
/* mm/slab.c */
// 在C文件中进行完整的定义
/*
* struct array_cache
*
* Purpose:
* - LIFO ordering, to hand out cache-warm objects from _alloc
* - reduce the number of linked list operations
* - reduce spinlock operations
*
* The limit is stored in the per-cpu structure to reduce the data cache
* footprint.
*
*/
// 这是每个CPU对应的cache数据
struct array_cache {
unsign