slab
数据结构
1 | struct kmem_cache { |
1 |
|
1 | struct slab { |
上面三者的关系
slab 在页面的外部
slab在页面的内部
跟踪空闲对象
1 | typedef unsigned int kmem_bufctl_t; |
kmem_bufctl_t 数组保存在slab描述符之后,并且没有指针直接指向第一个元素,所以需要提供辅助宏。1
2
((kmem_bufctl_t *)(((slab_t *)slabp)+1))
slabp+1是slab_t元素之后,其实就是kmem_bufctl_t的起始地址。
slab里下一个空闲对象的索引在slab_t->free中
指定大小的告诉缓存
数据结构
1 | struct cache_sizes { |
静态数组
1 |
|
per-CPU高速缓存
结构体array_cache,空闲对象的本地高速缓存的一个描述符1
2
3
4
5
6
7
8struct array_cache {
unsigned int avail; //指向本地高速缓存可用对象的指针的个数
unsigned int limit; //本地高速缓存的大小,也就是本地高速缓存中指针的最大个数
unsigned int batchcount; //本地高速缓存重新填充或者是腾空时使用的块大小
unsigned int touched; //如果本地高随缓存最近已经被使用过,就将该标志设置为1
spinlock_t lock;
void *entry[0];
};
结构体arraycache_init1
2
3
4
5struct arraycache_init {
struct array_cache cache;
void *entries[BOOT_CPUCACHE_ENTRIES];
};
static struct arraycache_init initarray_cache __initdata={{0,BOOT_CPUCACHE_ENTRIES,1,0}};
一些重要的全局变量
第一个高速缓存的描述符cache_cache,第一个高速缓存叫做kmem_cache,包含由内核使用的其余高速缓存的高速缓存描述符。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27static struct kmem_cache cache_cache = {
.batchcount = 1,
.limit = BOOT_CPUCACHE_ENTRIES,
.shared = 1.
.buffer_size = sizeof(struct kmem_cache),
.name = "kmem_cache",
};
//初始化
static void kmem_list3_init(struct kmem_list3 *parent)
{
INIT_LIST_HEAD(&parent->slabs_full);
INIT_LIST_HEAD(&parent->slabs_partial);
INIT_LIST_HEAD(&parent->slabs_free);
parent->shared = NULL;
parent->alien = NULL;
parent->colour_next = 0;
spin_lock_init(&parent->list_lock);
parent->free_objects = 0;
parent->free_touched = 0;
}
kmem_cache初始化函数
kmem_cache_init();
kmem_cache_create();//这个函数的最终实现是kmem_cache_zalloc()->kmem_cache_alloc(,|__GFP_ZERO)->__cache_alloc()->__do_cache_alloc()->____cache_alloc()
cache_alloc_refill()