Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1833702
  • 博文数量: 195
  • 博客积分: 4227
  • 博客等级: 上校
  • 技术积分: 2835
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-04 10:39
文章分类

全部博文(195)

文章存档

2013年(1)

2012年(26)

2011年(168)

分类:

2011-06-28 10:31:50

 

本节介绍如何销毁一个cache。

kmem_cache_destroy

 

void kmem_cache_destroy(struct kmem_cache *s)

{

       down_write(&slub_lock);

       /* cache的引用计数减一 */

       s->refcount--;

       /* 如果引用计数为0,说明没有对象使用此cache */

       if (!s->refcount) {

              /* cache链表中删除 */

              list_del(&s->list);

              /* 释放cache占用的资源 */

              if (kmem_cache_close(s)) {

                     printk(KERN_ERR "SLUB %s: %s called for cache that "

                            "still has objects.\n", s->name, __func__);

                     dump_stack();

              }

              if (s->flags & SLAB_DESTROY_BY_RCU)

                     rcu_barrier();

              /* sysfs中删除 */

              sysfs_slab_remove(s);

       }

       up_write(&slub_lock);

}

 

kmem_cache_close

    释放cache占用的资源。

static inline int kmem_cache_close(struct kmem_cache *s)

{

       int node;

       /* 调用flush_slab释放local slab */

       flush_all(s);

       /* 释放percpu空间 */

       free_percpu(s->cpu_slab);

       /* Attempt to free all objects */

       /* 循环释放每个内存节点的部分满slab */

       for_each_node_state(node, N_NORMAL_MEMORY) {

              struct kmem_cache_node *n = get_node(s, node);

              /* 释放部分满slab上的所有slab */

              free_partial(s, n);

              /* 释放完成后,计数不为0,返回错误 */

              if (n->nr_partial || slabs_node(s, node))

                     return 1;

       }

       /* 释放struct kmem_cache中的struct kmem_cache_node对象 */

       free_kmem_cache_nodes(s);

       return 0;

}

 

free_partial

 

static void free_partial(struct kmem_cache *s, struct kmem_cache_node *n)

{

       unsigned long flags;

       struct page *page, *h;

 

       spin_lock_irqsave(&n->list_lock, flags);

       /* 循环释放部分满slab链上的所有slab */

       list_for_each_entry_safe(page, h, &n->partial, lru) {

              if (!page->inuse) {

                     /* 从部分满slab链删除 */

                     __remove_partial(n, page);

                     /* 废除这个slab */

                     discard_slab(s, page);

              } else {

                     /* slab中还有在用的对象,错误 */

                     list_slab_objects(s, page,

                            "Objects remaining on kmem_cache_close()");

              }

       }

       spin_unlock_irqrestore(&n->list_lock, flags);

}

 

__remove_partial

 

static inline void __remove_partial(struct kmem_cache_node *n,

                                   struct page *page)

{

       /* 摘链 */

       list_del(&page->lru);

       /* 部分满slab数减一 */

       n->nr_partial--;

}

 

discard_slab

 

static void discard_slab(struct kmem_cache *s, struct page *page)

{

       /* 更新slab数和对象数 */

       dec_slabs_node(s, page_to_nid(page), page->objects);

       /* 释放slab */

       free_slab(s, page);

}

 

阅读(740) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~