2011年(38)
分类: LINUX
2011-04-25 11:16:11
本节介绍如何销毁一个slab块。
free_slab
销毁一个slab。
static void free_slab(struct kmem_cache *s, struct page *page)
{
if (unlikely(s->flags & SLAB_DESTROY_BY_RCU)) {
/*
* RCU free overloads the RCU head over the LRU
*/
/* rcu方式释放 */
struct rcu_head *head = (void *)&page->lru;
call_rcu(head, rcu_free_slab);
} else
/* 普通方式释放slab */
__free_slab(s, page);
}
__free_slab
释放slab所占页块。
static void (struct kmem_cache *s, struct page *page)
{
/* 获得order */
int order = compound_order(page);
/* 获得页数 */
int pages = 1 << order;
if (kmem_cache_debug(s)) {
void *p;
slab_pad_check(s, page);
for_each_object(p, s, page_address(page),
page->objects)
check_object(s, page, p, SLUB_RED_INACTIVE);
}
kmemcheck_free_shadow(page, compound_order(page));
mod_zone_page_state(page_zone(page),
(s->flags & SLAB_RECLAIM_ACCOUNT) ?
NR_SLAB_RECLAIMABLE : NR_SLAB_UNRECLAIMABLE,
-pages);
/* 清除slab标志位 */
__ClearPageSlab(page);
/* 重置pte映射计数,不使用这个page了,其映射的pte表项自然也没用了 */
reset_page_mapcount(page);
if (current->reclaim_state)
current->reclaim_state->reclaimed_slab += pages;
/* 释放slab所占页块 */
__free_pages(page, order);
}