歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Linux Slab分配器(七)--銷毀緩存

Linux Slab分配器(七)--銷毀緩存

日期:2017/3/1 10:19:09   编辑:Linux編程

銷毀緩存首先要保證的一點就是緩存當中所有的對象都是空閒的,也就是之前分配出去的對象都已經釋放回來了,其主要的步驟如下

1.將緩存從cache_chain鏈表中刪除

2.將本地高速緩存、alien高速緩存和共享本地高速緩存中的對象都釋放回slab並釋放所有的free鏈表,然後判斷full鏈表以及partial鏈表是否都為空,如果有一個不為空說明存在非空閒slab,也就是說有對象還未釋放,此時無法銷毀緩存,重新將緩存添加到cache_chain鏈表中

3.確定所有的slab都為空閒狀態後,將緩存涉及到的所有描述符都釋放(這些描述符都是保存在普通高速緩存中的)

相關閱讀:

Linux Slab分配器(一)--概述 http://www.linuxidc.com/Linux/2012-06/62965.htm
Linux Slab分配器(二)--初始化 http://www.linuxidc.com/Linux/2012-06/62966.htm
Linux Slab分配器(三)--創建緩存 http://www.linuxidc.com/Linux/2012-06/63109.htm
Linux Slab分配器(四)--分配對象 http://www.linuxidc.com/Linux/2012-06/63138.htm
Linux Slab分配器(五)--釋放對象 http://www.linuxidc.com/Linux/2012-06/63167.htm
Linux Slab分配器(六)--創建slab和銷毀slab http://www.linuxidc.com/Linux/2012-06/63229.htm

負責銷毀緩存的函數為kmem_cache_destroy()

  1. void kmem_cache_destroy(struct kmem_cache *cachep)
  2. {
  3. BUG_ON(!cachep || in_interrupt());
  4. /* Find the cache in the chain of caches. */
  5. get_online_cpus();
  6. mutex_lock(&cache_chain_mutex);
  7. /*
  8. * the chain is never empty, cache_cache is never destroyed
  9. */
  10. /*將cache從cache_chain中刪除*/
  11. list_del(&cachep->next);
  12. /*釋放完free鏈表,如果FULL鏈表或partial鏈表中還有slab,說明還有對象處於分配狀態
  13. 因此不能銷毀該緩存!*/
  14. if (__cache_shrink(cachep)) {
  15. slab_error(cachep, "Can't free all objects");
  16. /*重新將緩存添加到cache_chain鏈表中*/
  17. list_add(&cachep->next, &cache_chain);
  18. mutex_unlock(&cache_chain_mutex);
  19. put_online_cpus();
  20. return;
  21. }
  22. if (unlikely(cachep->flags & SLAB_DESTROY_BY_RCU))
  23. rcu_barrier();
  24. /*釋放cache所涉及到的各個描述符的存儲對象*/
  25. __kmem_cache_destroy(cachep);
  26. mutex_unlock(&cache_chain_mutex);
  27. put_online_cpus();
  28. }

  1. static int __cache_shrink(struct kmem_cache *cachep)
  2. {
  3. int ret = 0, i = 0;
  4. struct kmem_list3 *l3;
  5. /*將本地高速緩存,share本地高速緩存以及alien高速緩存的空閒對象釋放slab*/
  6. drain_cpu_caches(cachep);
  7. check_irq_on();
  8. for_each_online_node(i) {
  9. l3 = cachep->nodelists[i];
  10. if (!l3)
  11. continue;
  12. /*銷毀空閒鏈表中的slab*/
  13. drain_freelist(cachep, l3, l3->free_objects);
  14. /*判斷full和partial是否為空,有一個不為空則ret就為1*/
  15. ret += !list_empty(&l3->slabs_full) ||
  16. !list_empty(&l3->slabs_partial);
  17. }
  18. return (ret ? 1 : 0);
  19. }
Copyright © Linux教程網 All Rights Reserved