手机版
你好,游客 登录 注册 搜索
背景:
阅读新闻

Linux Slab分配器(六)--创建slab和销毁slab

[日期:2012-06-18] 来源:Linux社区  作者:vanbreaker [字体: ]

在满足以下两个条件时,slab分配器将为高速缓存创建新的slab

1.请求分配对象,但本地高速缓存没有空闲对象可以分配,需要填充

2.kmem_list3维护的链表中没有slab或者所有的slab都处于FULL链表中

这时,调用cache_grow()创建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

下图给出了cache_grow()的代码流程

 

  1. static int cache_grow(struct kmem_cache *cachep,  
  2.         gfp_t flags, int nodeid, void *objp)  
  3. {  
  4.     struct slab *slabp;  
  5.     size_t offset;  
  6.     gfp_t local_flags;  
  7.     struct kmem_list3 *l3;  
  8.   
  9.     /* 
  10.      * Be lazy and only check for valid flags here,  keeping it out of the 
  11.      * critical path in kmem_cache_alloc(). 
  12.      */  
  13.     BUG_ON(flags & GFP_SLAB_BUG_MASK);  
  14.     local_flags = flags & (GFP_CONSTRAINT_MASK|GFP_RECLAIM_MASK);  
  15.   
  16.     /* Take the l3 list lock to change the colour_next on this node */  
  17.     check_irq_off();  
  18.     l3 = cachep->nodelists[nodeid];  
  19.     spin_lock(&l3->list_lock);  
  20.   
  21.     /* Get colour for the slab, and cal the next value. */  
  22.     /*确定待创建的slab的颜色编号*/  
  23.     offset = l3->colour_next;  
  24.     /*更新下一个slab的颜色编号*/  
  25.     l3->colour_next++;  
  26.     /*颜色编号必须小于颜色数*/  
  27.     if (l3->colour_next >= cachep->colour)  
  28.         l3->colour_next = 0;  
  29.     spin_unlock(&l3->list_lock);  
  30.   
  31.     /*确定待创建的slab的颜色*/  
  32.     offset *= cachep->colour_off;  
  33.   
  34.     if (local_flags & __GFP_WAIT)  
  35.         local_irq_enable();  
  36.   
  37.     /* 
  38.      * The test for missing atomic flag is performed here, rather than 
  39.      * the more obvious place, simply to reduce the critical path length 
  40.      * in kmem_cache_alloc(). If a caller is seriously mis-behaving they 
  41.      * will eventually be caught here (where it matters). 
  42.      */  
  43.     kmem_flagcheck(cachep, flags);  
  44.   
  45.     /* 
  46.      * Get mem for the objs.  Attempt to allocate a physical page from 
  47.      * 'nodeid'. 
  48.      */  
  49.     if (!objp)  
  50.         /*从伙伴系统分配页框,这是slab分配器与伙伴系统的接口*/  
  51.         objp = kmem_getpages(cachep, local_flags, nodeid);  
  52.     if (!objp)  
  53.         goto failed;  
  54.   
  55.     /* Get slab management. */  
  56.     /*分配slab管理区*/  
  57.     slabp = alloc_slabmgmt(cachep, objp, offset,  
  58.             local_flags & ~GFP_CONSTRAINT_MASK, nodeid);  
  59.     if (!slabp)  
  60.         goto opps1;  
  61.   
  62.     /*建立页面到slab和cache的映射,以便于根据obj迅速定位slab描述符和cache描述符*/  
  63.     slab_map_pages(cachep, slabp, objp);  
  64.   
  65.     /*初始化对象*/  
  66.     cache_init_objs(cachep, slabp);  
  67.   
  68.     if (local_flags & __GFP_WAIT)  
  69.         local_irq_disable();  
  70.     check_irq_off();  
  71.     spin_lock(&l3->list_lock);  
  72.   
  73.     /* Make slab active. */  
  74.     /*将新创建的slab添加到free链表*/  
  75.     list_add_tail(&slabp->list, &(l3->slabs_free));  
  76.     STATS_INC_GROWN(cachep);  
  77.     l3->free_objects += cachep->num;  
  78.     spin_unlock(&l3->list_lock);  
  79.     return 1;  
  80. opps1:  
  81.     kmem_freepages(cachep, objp);  
  82. failed:  
  83.     if (local_flags & __GFP_WAIT)  
  84.         local_irq_disable();  
  85.     return 0;  
  86. }  
linux
相关资讯       Linux内存管理 
本文评论   查看全部评论 (0)
表情: 表情 姓名: 字数

       

评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款