Chinaunix首页 | 论坛 | 博客
  • 博客访问: 428749
  • 博文数量: 123
  • 博客积分: 2686
  • 博客等级: 少校
  • 技术积分: 1349
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-23 22:11
文章分类
文章存档

2012年(3)

2011年(10)

2010年(100)

2009年(10)

我的朋友

分类: LINUX

2010-10-20 17:12:52

 The kernel delegates this work to function cache_grow(),

/*
 * Grow (by 1) the number of slabs within a cache. This is called by
 * kmem_cache_alloc() when there are no active objs left in a cache.
 */

static int cache_grow(struct kmem_cache *cachep,
        gfp_t flags, int nodeid, void *objp)
{
    struct slab *slabp;
    size_t offset;
    gfp_t local_flags;
    struct kmem_list3 *l3;

    /*
     * Be lazy and only check for valid flags here, keeping it out of the
     * critical path in kmem_cache_alloc().
     */

    BUG_ON(flags & GFP_SLAB_BUG_MASK);
    local_flags = flags & (GFP_CONSTRAINT_MASK|GFP_RECLAIM_MASK);

    /* Take the l3 list lock to change the colour_next on this node */
    check_irq_off();
    l3 = cachep->nodelists[nodeid];
    spin_lock(&l3->list_lock);

    /* Get colour for the slab, and cal the next value. */
    offset = l3->colour_next;
    l3->colour_next++;
    if (l3->colour_next >= cachep->colour)
        l3->colour_next = 0;
    spin_unlock(&l3->list_lock);

    offset *= cachep->colour_off;

    if (local_flags & __GFP_WAIT)
        local_irq_enable();

    /*
     * The test for missing atomic flag is performed here, rather than
     * the more obvious place, simply to reduce the critical path length
     * in kmem_cache_alloc(). If a caller is seriously mis-behaving they
     * will eventually be caught here (where it matters).
     */

    kmem_flagcheck(cachep, flags);

    /*
     * Get mem for the objs. Attempt to allocate a physical page from
     * 'nodeid'.
     */

    if (!objp)
        objp = kmem_getpages(cachep, local_flags, nodeid);
    if (!objp)
        goto failed;

    /* Get slab management. */
    slabp = alloc_slabmgmt(cachep, objp, offset,
            local_flags & ~GFP_CONSTRAINT_MASK, nodeid);
    if (!slabp)
        goto opps1;

    slab_map_pages(cachep, slabp, objp);

    cache_init_objs(cachep, slabp);

    if (local_flags & __GFP_WAIT)
        local_irq_disable();
    check_irq_off();
    spin_lock(&l3->list_lock);

    /* Make slab active. */
    list_add_tail(&slabp->list, &(l3->slabs_free));
    STATS_INC_GROWN(cachep);
    l3->free_objects += cachep->num;
    spin_unlock(&l3->list_lock);
    return 1;
opps1:
    kmem_freepages(cachep, objp);
failed:
    if (local_flags & __GFP_WAIT)
        local_irq_disable();
    return 0;
}


阅读(848) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-10-21 11:37:10

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com