626788149 发表于 2015-12-07 20:04

关于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;
}

nswcfd 发表于 2015-12-08 16:48

大概是说page上的objects全被使用了(处于frozen状态?)
或者说,page上剩余的objects全部被本地cache接管了。

626788149 发表于 2015-12-08 17:47

回复 2# nswcfd


    谢谢您的回复,我已经想通了,差不多就是您说的意思

kerryxi 发表于 2015-12-08 21:27

通俗讲,如果c->page->objects大于0,则c->page->inuse为真,否则就为0了。
页: [1]
查看完整版本: 关于SLUB分配器的一个疑惑