全部博文(37)
分类: LINUX
2011-03-19 21:20:27
我们删除了暂时不必要的字段,这样看起来更加清晰明了,同时代码中也给了我们良好的注释信息。
这个结构体是用来描述高速缓存。需要注意的是:这个缓存与CPU CACHE是没有关系的,只是内存的一个或者几个连续页框。具体占用几个由unsigned int gfporder字段决定。
1)结构体的第一个元素为struct array_cache *array[NR_CPUS];这个字段是用来描述per-cpu高速缓存的,设计思想与页框分配器的
"每cpu页高速缓存"思想一致,如果你对后者不是很了解,OK,没关系,可以暂时忽略。每个CPU都有一个这样的对应结构体,也许你会
问为什么要每个CPU一个,所有CPU对应一个不可以吗?答案是这样做的好处是为了减少对锁得竞争,设想所有CPU共用一个这样的结构体,那么
你在想获取其中描述的对象之前必选要获得锁,才可以进行操作。
263 struct array_cache {
264 unsigned int avail;
265 unsigned int limit;
266 unsigned int batchcount;
267 unsigned int touched;
268 spinlock_t lock;
269 void *entry[0]; /*
270 * Must have this definition in here for the proper
271 * alignment of array_cache. Also simplifies accessing
272 * the entries.
273 * [0] is for gcc 2.95. It should really be [].
274 */
275 };
以上为struct array_cache的内容,在这里对各个参数进行解释是毫无必要的,但是有一点还是需要我们提前进行关注一下
最后的大小为0的指针数组,通过注释我们也可以看到,这是gcc(Version >=2.95)的特性,设想这样一个场景:
那么这个结构体得0字节数组指针就会指向物理内存上与struct array_cache A紧挨着的数据。同时另外的一个优点就是这个指针
不占用任何物理空间。这个特点很有用处,我们可以随着文章的深入了解到。(entry指针)
2) struct kmem_list3
这个结构体得定义如下:
其中包含三个链表 全满的slab,部分满的slab,和空闲的slab。
关系一眼明了。
3)结构体中还有一对构造函数和析构函数,不过没有实现。面向对象的思想,不错。调试的时候,你可以用一下。定义为自己的函数。
但是必须成对的定义,不能只定义一个,而不顾另一个。
随后我们还是跟着代码一起进军吧,看看slab分配器最初是如何建立起来的。
系统在初始化时 调用kmem_cache_init();这个函数在mem_init()之后调用,而我们知道mem_init负责伙伴系统的初始化。
也就是说:这时的伙伴系统已经建立,我们已经可以利用其进行连续页框的分配。
start_kernel()-->kmem_cache_init()-->kmem_list3_init()
在这个函数中首先初始化kmem_list3链表:
struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS];__initdata表示这个全局变量在装载时放入初始化数据段。
以便系统初始化好后,进行内存空间的释放。
调用kmem_list3_init函数对kmem_list3结构体进行初始化。把其中的三个链表(slabs_partial,slabs_full,slabs_free)初始化为指向
自己。同时把cache_cache的nodelist字段初始化为空。
cache_cache为kmem_cache_t类型,我们需要额外的说明一下。
在系统初始化期间,我们还没有建立起slab分配器,还无法进行小内存区域的分配,所以内核在初始化时手动的建立一些数据结构来构筑slab分配器
cache_cache为系统的第一个高速缓存,后续的数据结构的建立全部依赖与此高速缓存。cache_cache中很多成员都在系统编译时期得到初始化。
从其名字我们也可以得知一二,高速缓存的缓存。
我们在kmem_cache_init()中,对cache_cache剩余的变量进行初始化
cache_cache.nodelists[0] = NULL //指向kmem_list指针为空
1223 INIT_LIST_HEAD(&cache_chain);
1224 list_add(&cache_cache.next, &cache_chain);//将cache_cache 加入cache_chain中cache_cache.colour_off = cache_line_size();//cache_line_size()函数获得你的计算机的当前cache line大小,方便对齐,提高性能
//现在一般为128bytes,可以查看自己计算机的配置
(见二)