日期:2014-05-16 浏览次数:20716 次
释放对象和分配对象是一组对称的操作,同样分为两个路径:
1.如果待释放的对象所属的slab位于本地CPU缓存中,也就是slab处于冻结状态,则可直接释放
2.反之,待释放的对象所属的slab位于slab链表中,也就是slab处于解冻状态,则要通过慢速路径进行释放。
函数kmem_cache_free()用来将一个对象释放至对应的缓存中
释放对象前必须先得到对象所属slab的第一个页,这样便于后面判断slab是否处于本地CPU缓存中。
判断slab是否位于本地CPU缓存中的方式很简单,就是看本地CPU缓存中的page指针和之前获取的page指针是否相等,相等的话就表明两者指向同一个page,也就是说是同一个slab. 判断node>=0是为了辨明该非调试状态,因为node==-1是用来调试的。常规释放路径和分配是对称的操作,如果看懂了分配,那么这个自然也就明白了,不赘述了。下面来看慢速释放路径
首先获取本地CPU缓存结构,保存在c中,然后将对象释放回slab,注意这里用的是page->freelist而不是c->freelist
如果page->inuse为0,表示slab所有对象都是空闲的,slub没有free list链表,因此选择直接销毁该slab,将内存返回给伙伴系统。如果prior为空,那也就表示slab处于full slab链表而不是partial slab链表,由于现在获得了一个空闲对象,因此将slab添加到partial slab中,至于从full slab中删除slab的操作,是在free_debug_processing()中完成的。