计算Slab的Order,即该Slab是由几个页面构成
static inline size_t calculate_slab_order(struct kmem_cache *cachep,
size_t size, size_t align, unsigned long flags)
{
size_t left_over = 0;
int gfporder;
首先从order为0开始尝试,直到最大order(MAX_GFP_ORDER)为止
for (gfporder = 0 ; gfporder <= MAX_GFP_ORDER; gfporder++) {
unsigned int num;
size_t remainder;
调用cache计算函数,如果该order放不下一个size大小的object,即num为0,表示order太小,需要调整。
cache_estimate(gfporder, size, align, flags, &remainder, &num);
if (!num)
continue;
如果Slab管理区没有和对象存放在一起,并且该order存放对象数量大于
每个Slab允许存放最大的对象数量,则返回。
if ((flags & CFLGS_OFF_SLAB) && num > offslab_limit)
break;
找到了合适的order,将相关参数保存。
Slab中的对象数量
cachep->num = num;
order值
cachep->gfporder = gfporder;
Slab中的碎片大小
left_over = remainder;
SLAB_RECLAIM_ACCOUNT:内核检查用户态程序有没有足够内存可用,被标记为
这个标志的Slab将作为通缉对象。
if (flags & SLAB_RECLAIM_ACCOUNT)
break;
slab_break_gfp_order 定义为0,目前还不是很明白这是什么意思。
if (gfporder >= slab_break_gfp_order)
break;
Slab碎片的8倍大小还是小于Slab大小,那么这样的碎片是可以
接受的。
if ((left_over * 8) <= (PAGE_SIZE << gfporder))
break;
}
return left_over;
}