2014年(5)
分类: LINUX
2014-02-23 09:22:13
刚看了下Linux内核情景分析中的内核缓冲区管理,现在做个小总结,有不当之处,请大家不吝赐教。
在Linux内核中,对于大块的内存的管理是用伙伴系统算法(buddy )管理。对于小块的内存则用slab管理。
在slab方法中,每种重要的数据结构都有自己专用的缓冲区队列。每个队列中的“对象”的个数是动态变化的,不够时可以增添,空闲的时候可以释放,给系统回收。
slab中,每种对象的缓冲区队列并非由各种各个对象直接构成,而是由一连串的"大块"(slab结构)组成,每个大块中包含若干个对象。slab结构如下:
struct slab_s{
struct list_head list;//用来将slab链入专用的缓冲区队列
unsigned long colouroff;//本slab上着色区的大小
void *s_mem; //本slab对像区的起点
unsigned intinust;//已分配对象个数
kmem_bufctl_tfree;
}
每种对象建立的slab队列都有个队列头。结构是kmem_cache_t,该结构除了维持slab指针外还记录一些该对象的参数。系统中有个总的slab队列,其对象是其他对象的队列头。称为cache_cache。
不是内核所有的数据结构都专用的缓冲区队列。不太常用的数据结构使用通用的缓冲区队列,称为slab_cache。通用缓冲池的分配和释放函数:
void kmalloc(size, flags)
void free(void *objp);
1. 专用缓冲区的建立
kmem_cache_create(name,size,......);
该函数只是建立所需专用缓存队列的基础设施,所形成的slab队列是个空队列。而具体slab的创建则需要等分配时创建。
2. 缓冲区的分配
void *kmem_cache_alloc(kmem_cache_t *, flag)
该函数找到第一个空闲的slab,然后从slab的找到空闲队列,从该slab中分配一个对象,修改slab中free值,表示对象已分配。
3. 缓冲区对象释放
void kmem_cache_free(void *)
找到该对象所属slab,然后释放。调整slab所在的队列。
4. 缓冲区的销毁
void kmem_cache_free()
slab缓冲区中对象的组成示意图: