销毁缓存首先要保证的一点就是缓存当中所有的对象都是空闲的,也就是之前分配出去的对象都已经释放回来了,其主要的步骤如下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()
- void kmem_cache_destroy(struct kmem_cache *cachep)
- {
- BUG_ON(!cachep || in_interrupt());
-
- /* Find the cache in the chain of caches. */
- get_online_cpus();
- mutex_lock(&cache_chain_mutex);
- /*
- * the chain is never empty, cache_cache is never destroyed
- */
- /*将cache从cache_chain中删除*/
- list_del(&cachep->next);
-
- /*释放完free链表,如果FULL链表或partial链表中还有slab,说明还有对象处于分配状态
- 因此不能销毁该缓存!*/
- if (__cache_shrink(cachep)) {
- slab_error(cachep, "Can"t free all objects");
- /*重新将缓存添加到cache_chain链表中*/
- list_add(&cachep->next, &cache_chain);
- mutex_unlock(&cache_chain_mutex);
- put_online_cpus();
- return;
- }
-
- if (unlikely(cachep->flags & SLAB_DESTROY_BY_RCU))
- rcu_barrier();
-
- /*释放cache所涉及到的各个描述符的存储对象*/
- __kmem_cache_destroy(cachep);
- mutex_unlock(&cache_chain_mutex);
- put_online_cpus();
- }
- static int __cache_shrink(struct kmem_cache *cachep)
- {
- int ret = 0, i = 0;
- struct kmem_list3 *l3;
-
- /*将本地高速缓存,share本地高速缓存以及alien高速缓存的空闲对象释放slab*/
- drain_cpu_caches(cachep);
-
- check_irq_on();
- for_each_online_node(i) {
- l3 = cachep->nodelists[i];
- if (!l3)
- continue;
- /*销毁空闲链表中的slab*/
- drain_freelist(cachep, l3, l3->free_objects);
-
- /*判断full和partial是否为空,有一个不为空则ret就为1*/
- ret += !list_empty(&l3->slabs_full) ||
- !list_empty(&l3->slabs_partial);
- }
- return (ret ? 1 : 0);
- }