Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1030553
  • 博文数量: 123
  • 博客积分: 5051
  • 博客等级: 大校
  • 技术积分: 1356
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-14 10:56
文章分类
文章存档

2012年(1)

2011年(21)

2010年(13)

2009年(55)

2008年(33)

分类: LINUX

2009-07-30 21:10:33

kmem_cache_init用来初始化cache,在初始化阶段使用了全局静态变量cache_cache,这个变量是用来管理所有cache的kmem_cache的, 也就是说,在初始化阶段,将会创建一个slab,用来存放所有cache的kmem_cache,而创建kmem_cache是通过kmem_cache_create来创建的.所有cache的kmem_cache是根据linux/kmem_sizes.h文件中的所有cache来作为标准的,也就是创建8字节,16字节,32字节,64字节,128字节,256字节...所对应的cache.
kmem_cache_init可以分为五个阶段:
第一个阶段:是根据kmem_cache来设置cache_cache的字段值;

第二个阶段:首先是创建arraycache_init对应的高速缓存,同时也是在这个kmem_cache_create的调用过程中,创建了用于保存cache的kmem_cache的slab,并初始化了slab中的各个对象;

第三个阶段:创建kmem_list3对应的高速缓存,在这里要注意的一点是,如果sizeof(arraycache_t)和sizeof(kmem_list3)的大小一样大,那么就不再使用kmem_cache_create来为kmem_list3创建cache了,因为如果两者相等的话,两者就可以使用同一个cache;

第四个阶段:创建并初始化所有的通用cache和dma cache;

第五个阶段:创建两个arraycache_init对象,分别取代cache_cache中的array字段和malloc_sizes[INDEX_AC].cs_cachep->array字段;

第六个阶段:创建两个kmem_list3对象,取代cache_cache中的kmem_list3字段和malloc_sizes[INDEX_AC].cs_cachep->nodelist3字段.如此一来,经过上面的六个阶段后,所有的初始化工作基本完成了;

下面将来详细地解析每个阶段.
第一阶段:根据kmem_cache来设置cache_cache的字段值;此阶段比较简单,这里就不再详细地介绍了.

第二个阶段:首先是创建arraycache_init对应的高速缓存,同时也是在这个kmem_cache_create的调用过程中,创建了用于保存cache的kmem_cache的slab,并初始化了slab中的各个对象
sizes = malloc_sizes[INDEX_AC].cs_cachep = kmem_cache_create(names[INDEX_AC].name,
                            sizes[INDEX_AC].cs_size,
                            ARCH_KMALLOC_MINALIGN,
                            (ARCH_KMALLOC_FLAGS |
                            SLAB_PANIC),NULL,NULL);
kmem_cache_create()调用kmem_cache_alloc()获得cache的描述符对象.kmem_cache_alloc()的最终实现是函数____cache_alloc(struct kmem_cache *cachep,gfp_t flags)函数,在初始化阶段,____cache_alloc()函数调用cache_alloc_refill来创建slab并最终返回所分配对象的地址.关于cache_alloc_refill()函数的调用的条件是这样的:当slab中没有可用对象时,就会调用cache_alloc_refill函数来创建slab.cache_alloc_refill()的最终实现为cache_grow(),
cache_grow()函数创建slab,并为slab分配空间.对于mem_cache_create的返回值,我们会发现,最终的返回值的实现是函数cache_alloc_refill(),cache_alloc_refill()函数返回的是
array_cache->entry[--ac->avail];,这里我们来解说一下这个返回值.
在函数cache_alloc_refill中,有这样一段代码:
while(slabp->inuse < cachep->num && batchcount --) {
    STATS_INC_ALLOCED(cachep);
    STATS_INC_ACTIVE(cachep);
    STATS_SET_HIGH(cachep);
    ac->entry[ac->avail++] = slab_get_obj(cachep,slabp,numa_node_id());
}
这个循环中的最后一行代码就是用来实现对象的分配的最终分配的,这里我们会发现,之前为void *类型的entry指向的是高速缓存中分配好的对象的地址.这样,当在alloc_cache_refill()最后的返回值中,ac->entry[--ac->avail]就是一个kmem_cache对象的指针,这样就成功实现了kmem_cache_create()
的功能;

第三个阶段:创建kmem_list3对应的高速缓存,这个功能的实现是通过调用函数kmalloc(size,flags)来实现的,kmalloc函数将会从size对应的高速缓存中分配一个对象来满足要求,返回的是新分配对象的地址.第一个kmalloc的实现是从arraycache_init对应的高速缓存中分配出来的,kmalloc的最终实现
所调用的函数和kmem_cache_create相同,只是参数不同而已,一个是cache_cache,另外一个是通用cache;

第四个阶段:创建并初始化所有的通用cache和dma cache,这个过程是遍历malloc_sizes中的所有成员为每个成员创建一个cs_cachep,这个过程就是调用kmem_cache_create()来实现的;

第五个阶段:创建两个arraycache_init对象,分别取代cache_cache中的array字段和malloc_sizes[INDEX_AC].cs_cachep->array字段.这个过程也是调用kmalloc来实现的.

第六个阶段:创建两个kmem_list3对象,取代cache_cache中的kmem_list3字段和malloc_sizes[INDEX_AC].cs_cachep->nodelist3字段.

阅读(2912) | 评论(0) | 转发(3) |
给主人留下些什么吧!~~