最近把slab机制看了一下,网上分析内容丰富全面,不再过多赘述,只是自己做了个简单的小结
1. 几大重要数据结构
(1)Kmem_cache数据结构:
struct kmem_cache {
struct array_cache *array[NR_CPUS]; CPU本地高速缓存
unsigned int batchcount;
unsigned int limit;
unsigned int shared;
unsigned int buffer_size; slab对象的大小
u32 reciprocal_buffer_size; buffer_size的倒数,计算对象在slab中索引时用
unsigned int flags; 可区分slab管理区外置or内置
unsigned int num; 一个slab中对象的个数
unsigned int gfporder; 一个slab占用的页的order数
gfp_t gfpflags;
size_t colour; 一个slab中碎片区需要的着色块数
unsigned int colour_off; cache的着色块的单位大小
struct kmem_cache *slabp_cache; slab管理区域对象,slab外置方式时需要
unsigned int slab_size; slab管理对象的大小
num * sizeof(kmem_bufctl_t) + sizeof(struct slab)
unsigned int dflags;
void (*ctor)(void *obj); 对象构造函数
const char *name; 对象缓存的名字
struct list_head next; 链入全局slab cache链表中
#ifdef CONFIG_DEBUG_SLAB 统计数据
unsigned long num_active;
unsigned long num_allocations;
unsigned long high_mark;
unsigned long grown;
unsigned long reaped;
unsigned long errors;
unsigned long max_freeable;
unsigned long node_allocs;
unsigned long node_frees;
unsigned long node_overflow;
atomic_t allochit;
atomic_t allocmiss;
atomic_t freehit;
atomic_t freemiss;
int obj_offset;
int obj_size;
#endif /* CONFIG_DEBUG_SLAB */
struct kmem_list3 *nodelists[MAX_NUMNODES]; slab三链结构
}
(2)Slab三链数据结构:
struct kmem_list3 {
struct list_head slabs_partial; 非空非满slab链
struct list_head slabs_full; 满slab链
struct list_head slabs_free; 空slab链
unsigned long free_objects; slab链表的空闲对象数
unsigned int free_limit;
unsigned int colour_next; 当前slab的着色区偏移
spinlock_t list_lock;
struct array_cache *shared; 各local cache的共享对象cache
struct array_cache **alien;
unsigned long next_reap;
int free_touched; 表示刚刚访问了slab空链表
};
(3)各cpu缓存数据结构:
struct array_cache {
unsigned int avail; 当前local cache中可用对象索引
unsigned int limit; 当前local cache中对象个数限制
unsigned int batchcount; 批量填充的数目,local cache是按批填充的
unsigned int touched; 置1表示最近使用了local cache
spinlock_t lock; 自旋锁
void *entry[]; 指针数组
};
(4)slab数据结构:
struct slab {
struct list_head list;
unsigned long colouroff; 本slab的着色偏移
void *s_mem; slab中第一个对象的起始地址页面地址+colouroff+管理区大小
unsigned int inuse; 在用对象计数
kmem_bufctl_t free; 本slab中第一个空闲对象的索引
unsigned short nodeid; 所处的node号
};
Slab存放于页面地址+colouroff处
2. 一些重要操作
(1) 初始化
第一阶段 Start_kernel()->mm_init()->kmem_cache_init()
第二阶段 Start_kernel()->kmem_cache_init_late()
(2) 创建cache
kmem_cache_create()
截取网上众多分析中的图
众Kmem_cache者的关系图:
(3) 创建slab
cache_grow()
alloc_slabmgmt():
slab_map_pages():
分配对象
先查看本地CPU cache,然后是本地共享CPU cache,最后是三链。前面三个都没有空间时,需要从新分配slab。