关于SLUB分配器的一个疑惑
本帖最后由 626788149 于 2015-12-08 11:37 编辑问题已经解决。
最近一直在写操作系统,写到内存管理那块了。想实现一个SLUB分配器。
差不多实现完成了,不过出现了SMP的同步问题,还没被释放的对象可能会被分配出去,我差不多是按照linux的SLUB系统写的。
如果在SLUB分配接口加上一把大锁,同步问题就不会出现。
我一直没看懂第27行。
c->page->inuse = c->page->objects;
可能同步问题跟inuse这个值有关。
谁能告诉我c->page->inuse = c->page->objects; 这行是啥意思?static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
unsigned long addr, struct kmem_cache_cpu *c)
{
void **object;
struct page *new;
/* We handle __GFP_ZERO in the caller */
gfpflags &= ~__GFP_ZERO;
if (!c->page)/*本地CPU的slab结构中没有存储可分配的内存,则要为其寻找新的slab*/
goto new_slab;
slab_lock(c->page);
if (unlikely(!node_match(c, node)))//节点不匹配
goto another_slab;
stat(c, ALLOC_REFILL);
load_freelist:
object = c->page->freelist;//获取一个对象
if (unlikely(!object))
goto another_slab;
if (unlikely(SLABDEBUG && PageSlubDebug(c->page)))
goto debug;
c->freelist = object; //更新freelist
c->page->inuse = c->page->objects;
/*一旦slab从partial slab链表转移到本地CPU,则page_freelist不再负责维护空闲对象了,
因此设为NULL*/
c->page->freelist = NULL;
c->node = page_to_nid(c->page);
unlock_out:
slab_unlock(c->page);
stat(c, ALLOC_SLOWPATH);
return object; //返回对象
another_slab:
deactivate_slab(s, c);//将本地CPU的slab移回partial slab链表
new_slab:
/*从partial slab链表中寻找一个slab*/
new = get_partial(s, gfpflags, node);
if (new) {/*获取成功则直接将该slab交给本地CPU*/
c->page = new;
stat(c, ALLOC_FROM_PARTIAL);
goto load_freelist;
}
if (gfpflags & __GFP_WAIT)
local_irq_enable();
/*如果partial slab链表中已无法获取slab则创建新的slab*/
new = new_slab(s, gfpflags, node);
if (gfpflags & __GFP_WAIT)
local_irq_disable();
if (new) {//创建成功
c = get_cpu_slab(s, smp_processor_id());//获取本地CPU的slab信息结构
stat(c, ALLOC_SLAB);
if (c->page)//本地CPU中存在slab,则移除该slab
flush_slab(s, c);
slab_lock(new);
__SetPageSlubFrozen(new);//冻结slab,表明slab处于本地CPU中
c->page = new;//本地CPU中的slab设置为新创建的slab
goto load_freelist;
}
if (!(gfpflags & __GFP_NOWARN) && printk_ratelimit())
slab_out_of_memory(s, gfpflags, node);
return NULL;
debug:
if (!alloc_debug_processing(s, c->page, object, addr))
goto another_slab;
c->page->inuse++;
c->page->freelist = object;
c->node = -1;
goto unlock_out;
} 大概是说page上的objects全被使用了(处于frozen状态?)
或者说,page上剩余的objects全部被本地cache接管了。 回复 2# nswcfd
谢谢您的回复,我已经想通了,差不多就是您说的意思 通俗讲,如果c->page->objects大于0,则c->page->inuse为真,否则就为0了。
页:
[1]