Linux SLUB分配器之四(kmem_cache初始化代码分析)

static struct kmem_cache *create_kmalloc_cache(struct kmem_cache *s,

              const char *name, int size, gfp_t gfp_flags)

{

       unsigned int flags = 0;

       if (gfp_flags & SLUB_DMA)

              flags = SLAB_CACHE_DMA;

       down_write(&slub_lock);

       if (!kmem_cache_open(s, gfp_flags, name, size, ARCH_KMALLOC_MINALIGN,

                     flags, NULL))

              goto panic;

       list_add(&s->list, &slab_caches);

       up_write(&slub_lock);

       if (sysfs_slab_add(s))

              goto panic;

       return s;

panic:

       panic("Creation of kmalloc slab %s size=%d failed./n", name, size);

}

 

static int kmem_cache_open(struct kmem_cache *s, gfp_t gfpflags,

              const char *name, size_t size,

              size_t align, unsigned long flags,

              void (*ctor)(struct kmem_cache *, void *))

{

       memset(s, 0, kmem_size);

       s->name = name;

       s->ctor = ctor;

       s->objsize = size;/*objsize 就是对象的实际大小 */

       s->align = align;

       s->flags = kmem_cache_flags(size, flags, name, ctor);

 

       if (!calculate_sizes(s))/* 这个函数其实挺重要的,它将 kmem_cache -> offset 成员计算出来,这个成员的位置以后指明一个指针,该指针指向何处存放下一个空闲对象,对象后一般仅接着就是这个指针,但在需要对其的情况下,会往后移一些;该函数同时还计算出 kmem_cache -> size 成员,该成员表明一个对象实际在内存里面需要的长度,这个长度包括了对象本身的长度,其后指向下一个空闲对象的指针长度, SLUB Debug 的情况下,要加入一个空区域用于越界监管的长度,对齐所需长度等;然后,该函数再根据该 kmem_cache 的单个 SLAB 所包含的物理页面的数目 ( 放在了 kmem_cache->order 成员李,也是根据 kmem_cache -> size 算出来的 ) ,及单个对象的实际长度 kmem_cache -> size ,计算出来单个 SLAB 所能容纳的对象的个数,放在了 kmem_cache ->objects 成员里。 */

              goto error;

 

       s->refcount = 1;

#ifdef CONFIG_NUMA

       s->defrag_ratio = 100;

#endif

       if (!init_kmem_cache_nodes(s, gfpflags & ~SLUB_DMA))/* 这个函数只是初始化了 kmem_cache -> local_node 成员,比如其 nr_partial 0 ,表示没有 Partial SLAB 在上面 */

              goto error;

 

       if (alloc_kmem_cache_cpus(s, gfpflags & ~SLUB_DMA))/* 这个函数只是初始化了 kmem_cache ->kmem_cache_cpu 成员,比如其 kmem_cache_cpu NULL ,表示没有当前 SLAB*/

              return 1;

       free_kmem_cache_nodes(s);

error:

       if (flags & SLAB_PANIC)

              panic("Cannot create slab %s size=%lu realsize=%u "

                     "order=%u offset=%u flags=%lx/n",

                     s->name, (unsigned long)size, s->size, s->order,

                     s->offset, flags);

       return 0;

}

 


版权声明:本文为huang_gao原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。