下面重点看calculate_order这个函数

static inline int calculate_order(int size, int reserved)
{
???
//尝试找到order与object数量的最佳配合方案
//期望的效果就是剩余的碎片最小
min_objects = slub_min_objects;
if (!min_objects)
min_objects = 4 * (fls(nr_cpu_ids) + 1);
max_objects = order_objects(slub_max_order, size, reserved);
min_objects = min(min_objects, max_objects);
//fraction是碎片因子,需要满足的条件是碎片部分乘以fraction小于slab大小
// (slab_size - reserved) % size <= slab_size / fraction
while (min_objects > 1) {
fraction = 16;
while (fraction >= 4) {
order = slab_order(size, min_objects,
slub_max_order, fraction, reserved);
if (order <= slub_max_order)
return order;
//放宽条件,容忍的碎片大小增倍
fraction /= 2;
}
min_objects--;
}
//尝试一个slab只包含一个对象
order = slab_order(size, 1, slub_max_order, 1, reserved);
if (order <= slub_max_order)
return order;
//使用MAX_ORDER且一个slab只含一个对象
order = slab_order(size, 1, MAX_ORDER, 1, reserved);
if (order < MAX_ORDER)
return order;
return -ENOSYS;
}
4 释放对象
从上面申请对象的流程也可以看出,释放的object有几个去处:
1)cpu本地缓存slab,也就是cpu_slab;
2)放回object所在的page(也就是slab)中;另外要处理所在的slab:
2.1)如果放回之后,slab完全为空,则直接销毁该slab;
2.2)如果放回之前,slab为满,则判断slab是否已被冻结;如果已冻结,则不需要做其他事;如果未冻结,则将其冻结,放入cpu_slab的partial队列;如果cpu_slab partial队列过多,则将队列中所有slab一次性解冻到各自node的partial队列中。
值得注意的是cpu partial队列的功能是个可选项,依赖于内核选项CONFIG_SLUB_CPU_PARTIAL,如果没有开启,则不使用cpu partial队列,直接使用各个node的partial队列。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-76918-4.html
美国害的伊拉克还不够惨吗
茶馆