kernel hacker修炼之道之内存管理-SLUB(创建SLAB块new_slab())

创建SLAB块new_slab()

作者:李万鹏 于北京 borqs


SLUB分配器调用new_slab()来分配新的SLAB块,可以看到已经用SLAB块的第一个物理页框的page结构代替slab描述符了。


static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node)
{
struct page *page;
void *start;
void *last;
void *p;

BUG_ON(flags & GFP_SLAB_BUG_MASK);
/*为slab块分配物理页框*/
page = allocate_slab(s,
flags & (GFP_RECLAIM_MASK | GFP_CONSTRAINT_MASK), node);
if (!page)
goto out;
/*slab数加一*/
inc_slabs_node(s, page_to_nid(page), page->objects);
page->slab = s;
page->flags |= 1 << PG_slab;
/*返回slab块的第一个页框对应的线性地址*/
start = page_address(page);
/*用于调试*/
if (unlikely(s->flags & SLAB_POISON))
memset(start, POISON_INUSE, PAGE_SIZE << compound_order(page));
/*初始化slab块中的每一个对象*/
last = start;
for_each_object(p, s, start, page->objects) {
/*调用构造函数*/
setup_object(s, page, last);
/*指向下一个对象*/
set_freepointer(s, last, p);
last = p;
}
/*设置最后一个对象*/
setup_object(s, page, last);
set_freepointer(s, last, NULL);

page->freelist = start;
page->inuse = 0;
out:
return page;
}

static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node)
{
struct page *page;
struct kmem_cache_order_objects oo = s->oo;
gfp_t alloc_gfp;

flags |= s->allocflags;

/*
* Let the initial higher-order allocation fail under memory pressure
* so we fall-back to the minimum order allocation.
*/
alloc_gfp = (flags | __GFP_NOWARN | __GFP_NORETRY) & ~__GFP_NOFAIL;

/*从buddy system分配物理页框,oo成员的高位保存页面的order,低位保存对象的个数。*/
page = alloc_slab_page(alloc_gfp, node, oo);
if (unlikely(!page)) {
/*如果没有分配到,调小分配的页框order,再次重试*/
oo = s->min;
/*
* Allocation may have failed due to fragmentation.
* Try a lower order alloc if possible
*/
page = alloc_slab_page(flags, node, oo);
if (!page)
return NULL;
stat(s, ORDER_FALLBACK);
}
if (kmemcheck_enabled
&& !(s->flags & (SLAB_NOTRACK | DEBUG_DEFAULT_FLAGS))) {
int pages = 1 << oo_order(oo);
kmemcheck_alloc_shadow(page, oo_order(oo), flags, node);
/*
* Objects from caches that have a constructor don't get
* cleared when they're allocated, so we need to do it here.
*/
if (s->ctor)
kmemcheck_mark_uninitialized_pages(page, pages);
else
kmemcheck_mark_unallocated_pages(page, pages);
}
/*得到slab块的对象数*/
page->objects = oo_objects(oo);
mod_zone_page_state(page_zone(page),
(s->flags & SLAB_RECLAIM_ACCOUNT) ?
NR_SLAB_RECLAIMABLE : NR_SLAB_UNRECLAIMABLE,
1 << oo_order(oo));
return page;
}

static void setup_object(struct kmem_cache *s, struct page *page,
void *object)
{
setup_object_debug(s, page, object);
/*如果构造函数存在,调用构造函数初始化对象*/
if (unlikely(s->ctor))
s->ctor(object);
}

static inline void set_freepointer(struct kmem_cache *s, void *object, void *fp)
{
*(void **)(object + s->offset) = fp;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值