免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5456 | 回复: 9
打印 上一主题 下一主题

SLUB的freelist指针问题 [复制链接]

论坛徽章:
16
2015亚冠之吉达阿赫利
日期:2015-08-17 11:21:462015年迎新春徽章
日期:2015-03-04 09:58:11酉鸡
日期:2014-12-07 09:06:19水瓶座
日期:2014-11-04 14:23:29天秤座
日期:2014-03-02 08:57:52双鱼座
日期:2014-02-22 13:07:56午马
日期:2014-02-14 11:08:18双鱼座
日期:2014-02-13 11:09:37卯兔
日期:2014-02-06 15:10:34子鼠
日期:2014-01-20 14:48:19戌狗
日期:2013-12-19 09:37:46射手座
日期:2013-12-19 09:33:47
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-09-14 20:03 |只看该作者 |倒序浏览
kmem_cache_cpu *c;
c->freelist与c->page->freelist含义一样吗?

论坛徽章:
16
2015亚冠之吉达阿赫利
日期:2015-08-17 11:21:462015年迎新春徽章
日期:2015-03-04 09:58:11酉鸡
日期:2014-12-07 09:06:19水瓶座
日期:2014-11-04 14:23:29天秤座
日期:2014-03-02 08:57:52双鱼座
日期:2014-02-22 13:07:56午马
日期:2014-02-14 11:08:18双鱼座
日期:2014-02-13 11:09:37卯兔
日期:2014-02-06 15:10:34子鼠
日期:2014-01-20 14:48:19戌狗
日期:2013-12-19 09:37:46射手座
日期:2013-12-19 09:33:47
2 [报告]
发表于 2011-09-15 10:59 |只看该作者
顶起!

论坛徽章:
0
3 [报告]
发表于 2011-09-15 20:04 |只看该作者
不一样,c的freelist是fastpath的,而page的那个是slow的

也就是说,走fast的话申请很快,如果走slow的话就慢

这个和slub的配置及flags有关,c的freelist的如果在未满的情况下,会很快

论坛徽章:
16
2015亚冠之吉达阿赫利
日期:2015-08-17 11:21:462015年迎新春徽章
日期:2015-03-04 09:58:11酉鸡
日期:2014-12-07 09:06:19水瓶座
日期:2014-11-04 14:23:29天秤座
日期:2014-03-02 08:57:52双鱼座
日期:2014-02-22 13:07:56午马
日期:2014-02-14 11:08:18双鱼座
日期:2014-02-13 11:09:37卯兔
日期:2014-02-06 15:10:34子鼠
日期:2014-01-20 14:48:19戌狗
日期:2013-12-19 09:37:46射手座
日期:2013-12-19 09:33:47
4 [报告]
发表于 2011-09-16 09:39 |只看该作者
回复 3# unbutun




奥,代码里确实如您所说,不过看这张图page与freelist是指向同一个slab阿。感觉就跟左手倒右手似的,为什么这里分fastpath,slowpath阿,本来就是指向同一个地方。求指点!

论坛徽章:
0
5 [报告]
发表于 2011-09-16 09:51 |只看该作者
恳请楼主告诉我帖子上用的图片是什么资料上的?我觉的图画的真不错

论坛徽章:
0
6 [报告]
发表于 2011-09-16 20:19 |只看该作者
回复 4# embeddedlwp


    fastpath 和 slowpath是指代码的流程,这张图说明不了什么问题,不用再往下追了,没意义

论坛徽章:
0
7 [报告]
发表于 2016-02-05 18:29 |只看该作者
我今天刚好也在看这个问题,代码在mm/slub.c
static inline void *get_freelist(struct kmem_cache *s, struct page *page)
{
        struct page new;
        unsigned long counters;
        void *freelist;

        do {
                freelist = page->freelist;
                counters = page->counters;

                new.counters = counters;
                VM_BUG_ON(!new.frozen);

                new.inuse = page->objects;
                new.frozen = freelist != NULL;

        } while (!__cmpxchg_double_slab(s, page,
                freelist, counters,
                NULL, new.counters,
                "get_freelist"));

        return freelist;
}
从这段代码可以看到,他们是不一样的。

论坛徽章:
2
程序设计版块每日发帖之星
日期:2016-01-13 06:20:00程序设计版块每日发帖之星
日期:2016-02-09 06:20:00
8 [报告]
发表于 2016-02-06 11:28 |只看该作者
都指向下一个空闲对象的地址,只不过一个是由kmem_cache_cpu得到(快速),另一个是遍历半满队列得到(慢速);

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-13 06:20:00数据库技术版块每日发帖之星
日期:2016-06-15 06:20:00数据库技术版块每日发帖之星
日期:2016-06-16 06:20:00数据库技术版块每日发帖之星
日期:2016-06-18 06:20:00程序设计版块每日发帖之星
日期:2016-06-27 06:20:00程序设计版块每日发帖之星
日期:2016-07-09 06:20:00IT运维版块每日发帖之星
日期:2016-07-15 06:20:00IT运维版块每日发帖之星
日期:2016-07-27 06:20:00程序设计版块每日发帖之星
日期:2016-08-18 06:20:00
9 [报告]
发表于 2017-06-06 17:46 |只看该作者
qiuxishi 发表于 2016-02-06 11:28
都指向下一个空闲对象的地址,只不过一个是由kmem_cache_cpu得到(快速),另一个是遍历半满队列得到(慢速 ...

没遍历啊, 也挺快啊
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[c->offset]; //更新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->offset];  
    c->node = -1;  
    goto unlock_out;  
}  


论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-13 06:20:00数据库技术版块每日发帖之星
日期:2016-06-15 06:20:00数据库技术版块每日发帖之星
日期:2016-06-16 06:20:00数据库技术版块每日发帖之星
日期:2016-06-18 06:20:00程序设计版块每日发帖之星
日期:2016-06-27 06:20:00程序设计版块每日发帖之星
日期:2016-07-09 06:20:00IT运维版块每日发帖之星
日期:2016-07-15 06:20:00IT运维版块每日发帖之星
日期:2016-07-27 06:20:00程序设计版块每日发帖之星
日期:2016-08-18 06:20:00
10 [报告]
发表于 2017-06-06 18:51 来自手机 |只看该作者
我想问,当cpu_cache freelist空时,不是说明cpu cache里已经没有空闲内存了么,怎么还在cpu cache里搞啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP