在满足以下两个条件时,slab分配器将为高速缓存创建新的slab
1.请求分配对象,但本地高速缓存没有空闲对象可以分配,需要填充
2.kmem_list3维护的链表中没有slab或者所有的slab都处于FULL链表中
这时,调用cache_grow()创建slab增大缓存容量
相关阅读:
Linux Slab分配器(一)--概述
Linux Slab分配器(二)--初始化
Linux Slab分配器(三)--创建缓存
Linux Slab分配器(四)--分配对象
下图给出了cache_grow()的代码流程

static int cache_grow(struct kmem_cache *cachep,
gfp_t flags, int nodeid, void *objp)
{
struct slab *slabp;
size_t offset;
gfp_t local_flags;
struct kmem_list3 *l3;
BUG_ON(flags & GFP_SLAB_BUG_MASK);
local_flags = flags & (GFP_CONSTRAINT_MASK|GFP_RECLAIM_MASK);
check_irq_off();
l3 = cachep->nodelists[nodeid];
spin_lock(&l3->list_lock);
offset = l3->colour_next;
l3->colour_next++;
if (l3->colour_next >= cachep->colour)
l3->colour_next = 0;
spin_unlock(&l3->list_lock);
offset *= cachep->colour_off;
if (local_flags & __GFP_WAIT)
local_irq_enable();
kmem_flagcheck(cachep, flags);
if (!objp)
objp = kmem_getpages(cachep, local_flags, nodeid);
if (!objp)
goto failed;
slabp = alloc_slabmgmt(cachep, objp, offset,
local_flags & ~GFP_CONSTRAINT_MASK, nodeid);
if (!slabp)
goto opps1;
slab_map_pages(cachep, slabp, objp);
cache_init_objs(cachep, slabp);
if (local_flags & __GFP_WAIT)
local_irq_disable();
check_irq_off();
spin_lock(&l3->list_lock);
list_add_tail(&slabp->list, &(l3->slabs_free));
STATS_INC_GROWN(cachep);
l3->free_objects += cachep->num;
spin_unlock(&l3->list_lock);
return 1;
opps1:
kmem_freepages(cachep, objp);
failed:
if (local_flags & __GFP_WAIT)
local_irq_disable();
return 0;
}
内容版权声明:除非注明,否则皆为本站原创文章。
转载注明出处:http://www.heiqu.com/psgzz.html