- 论坛徽章:
- 0
|
__slab_free
待释放对象所在slab并不是本cpu的local slab时,走慢速路径释放,
static void __slab_free(struct kmem_cache *s, struct page *page,
void *x, unsigned long addr)
{
void *prior;
void **object = (void *)x;
stat(s, FREE_SLOWPATH);
slab_lock(page);
if (kmem_cache_debug(s))
goto debug;
checks_ok:
/* 放回所在slab freelist的链表头部 */
prior = page->freelist;
/* 待释放对象的下一对象指针指向原freelist */
set_freepointer(s, object, prior);
/* freelist指向待释放的对象 */
page->freelist = object;
/* 已分配对象数减一 */
page->inuse--;
/* slab是否是冻结的。该slab有可能是其他cpu的local slab,这种情况下,不能执行后面的语句将local slab添加进部分满slab链 */
if (unlikely(PageSlubFrozen(page))) {
stat(s, FREE_FROZEN);
goto out_unlock;
}
/* inuse 为0,又不是local slab,说明slab中全部是空闲对象,并且在部分满slab链表上(slab只有一个对象时,在满slab链上)。*/
if (unlikely(!page->inuse))
goto slab_empty;
/*
* Objects left in the slab. If it was not on the partial list before
* then add it.
*/
/* 如果slab原本是满slab,现在释放了一个,加入部分满slab链 */
if (unlikely(!prior)) {
add_partial(get_node(s, page_to_nid(page)), page, 1);
stat(s, FREE_ADD_PARTIAL);
}
out_unlock:
slab_unlock(page);
return;
slab_empty:
if (prior) {
/*
* Slab still on the partial list.
*/
/* prior不为空时,说明slab在部分满slab链表上。prior为空时,说明slab只有一个对象,在满slab链上 */???
remove_partial(s, page);
stat(s, FREE_REMOVE_PARTIAL);
}
slab_unlock(page);
stat(s, FREE_SLAB);
/* 废除slab,slub没有空slab链,slab一旦为空,马上销毁。(这点与去解冻slab时不同,参见unfreeze_slab) */
discard_slab(s, page);
return;
debug:
if (!free_debug_processing(s, page, x, addr))
goto out_unlock;
goto checks_ok;
}
当流程执行到slab_empty处prior为空时,说明处于node full队列,而此时inuse不应当slab所有对象都在使用中么?
即某个slab不是cpu local slab时,若其首page处于page->inuse = 0 && ! PageSlubFrozen(page),为什么还有处于node的full队列下的可能性么?
当inuse == 0,不是应该在node的partial队列么? |
|