slab的基本概念(二)

kmem_list3链表

kmem_list3的定义如下:

 273 struct kmem_list3 {                                                                                                                                                                                   
 274         struct list_head        slabs_partial;  /* partial list first, better asm code */
 275         struct list_head        slabs_full;                                     
 276         struct list_head        slabs_free;                                     
 277         unsigned long   free_objects;                                           
 278         int             free_touched;                                           
 279         unsigned long   next_reap;                                              
 280         struct array_cache      *shared;                                        
 281 };

1)这个链表的作用是连接slab描述符和高速缓存。
高速缓存kmem_cache_s的定义如下:

 302 struct kmem_cache_s {                                                           
 303 /* 1) per-cpu data, touched during every alloc/free */                          
 304         struct array_cache      *array[NR_CPUS];                                
 305         unsigned int            batchcount;                                     
 306         unsigned int            limit;                                          
 307 /* 2) touched by every alloc & free from the backend */                         
 308         struct kmem_list3       lists; 
 ...
 }

在308行,是kmem_list3类型的lists,下面分析下从buddy分配一个slab,然后怎么挂到高速缓存上的链表。
cache_grow函数的定义如下:

1780 static int cache_grow (kmem_cache_t * cachep, int flags, int nodeid)            
1781 {
..
1847         /* Make slab active. */                                                 
1848         list_add_tail(&slabp->list, &(list3_data(cachep)->slabs_free));         
1849         STATS_INC_GROWN(cachep); 
...

list3_data的定义如下:

 289 #define list3_data(cachep) \                                                                                                                                                                          
 290         (&(cachep)->lists)  

就是把slab描述符的list链表挂到高速缓存的lists链表中的slabs_free链表,这样就实现了高速缓存和slab描述符的连接。通过高速缓存,再通过高速缓存lists->slab_free中找到slab。slab

链表策略

有3种类型的链表:
slabs_partial: 这个链表中的slab节点中object部分是空闲的。
slabs_free: 这个链表中的slab节点中object都是空闲的。
slabs_full: 这个链表中的slab节点中object没有空闲的

在从slab中选取object,提冲cache的函数定义如下:

1983 static void* cache_alloc_refill(kmem_cache_t* cachep, int flags)                
1984 {                                                                               
1985         int batchcount;                                                         
1986         struct kmem_list3 *l3;                                                  
1987         struct array_cache *ac;  
.......
2017         while (batchcount > 0) {                                                
2018                 struct list_head *entry;                                        
2019                 struct slab *slabp;                                             
2020                 /* Get slab alloc is to come from. */                           
2021                 entry = l3->slabs_partial.next;                                 
2022                 if (entry == &l3->slabs_partial) {                              
2023                         l3->free_touched = 1;                                   
2024                         entry = l3->slabs_free.next;                            
2025                         if (entry == &l3->slabs_free)                           
2026                                 goto must_grow;                                 
2027                 }                                                               
2028                
....
}                                                                                                      

说明:
1)在2021行,先从lists 中的slab_partial提取slab,然后从slab中提取object。
2)如果lists中的slab_partial链表没有slab了,则从lists中的slabs_free中提取slab,然后提取object。

2.释放object

  1. 把cache中array_cache的object,释放到相应的slab中,并把slab从3个链表所在的链表中删除。
  2. 如果释放后object后slab中的object都是空闲的,并判断3个链表中的可用oject是否大于限制值,如果是
    则销毁这个slab并把内存归还给buddy系统。如果3个链表总的可用object小于等于限制值,则把这个slab挂在free链表上。
  3. 如果slab中部分空闲,还把这个slab挂载partial链表上。
2163 static void free_block(kmem_cache_t *cachep, void **objpp, int nr_objects)      
2164 {                                                                               
2165         int i;                                                                  
2166                                                                                 
2167         check_spinlock_acquired(cachep); 
......
2194                 /* fixup slab chains */                                         
2195                 if (slabp->inuse == 0) {                                        
2196                         if (cachep->lists.free_objects > cachep->free_limit) {  
2197                                 cachep->lists.free_objects -= cachep->num;      
2198                                 slab_destroy(cachep, slabp);                                                                                                                                          
2199                         } else {                                                
2200                                 list_add(&slabp->list,                          
2201                                 &list3_data_ptr(cachep, objp)->slabs_free);     
2202                         }                                                       
2203                 } else {                                                        
2204                         /* Unconditionally move a slab to the end of the        
2205                          * partial list on free - maximum time for the          
2206                          * other objects to be freed, too.                      
2207                          */                                                     
2208                         list_add_tail(&slabp->list,                             
2209                                 &list3_data_ptr(cachep, objp)->slabs_partial);  
2210                 }                                                               
2211         }                                                                       
2212 }  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值