优雅的slab内存分配器(二)——slab初始化kmem_cache_init

本文详细探讨了slab内存分配器初始化过程中的关键函数,如calculate_alignment、calculate_slab_order和kmalloc_index。通过对这些函数的分析,揭示了slab内存分配如何按硬件缓存行对齐,以及如何根据内存大小选择合适的kmalloc_caches。同时,文章介绍了如何创建和管理kmem cache实例,确保内存分配的效率和对齐要求。
摘要由CSDN通过智能技术生成

slab内存分配器初始化有函数kmem_cache_init来完成,本文会详细介绍slab内存分配器的初始化流程。

软件架构


kmem_cache_init
   |----->kmem_cache = &kmem_cache_boot;
   |        第一个kmem cache实例,静态定义,不过尚需必须要的初始化
   |----->kmem_cache_node_init(&init_kmem_cache_node[i]);
   |        初始化静态定义的struct kmem_cache_node实例,这里有两个node实例;它们是分别为前两个
   |        kmem cache实例准备的,第一个kmem cache实例用于为创建其他kmem cache实例分配空间,
   |        第二个kmem cache实例用于为创建struct kmem_cache_node实例分配空间,所以前两个kmem cache
   |        实例需要静态分配struct kmem_cache_node实例。
   |----->create_boot_cache(kmem_cache, "kmem_cache", offsetof(struct kmem_cache, node) +
   |              nr_node_ids * sizeof(struct kmem_cache_node *),SLAB_HWCACHE_ALIGN);
   |        完成第一个kmem cache实例kmem_cache的初始化,第三个参数很重要,是该kmem cache实例所维护
   |        的object的size。
   |   |----->s->size = s->object_size = size;
   |   |      设置object size
   |   |----->s->align = calculate_alignment(flags, ARCH_KMALLOC_MINALIGN, size);
   |   |      计算按多少字节对齐,详见重要函数分析。
   |   |----->err = __kmem_cache_create(s, flags);
   |   |   |----->set_objfreelist_slab_cache(cachep, size, flags)
   |   |   |   |----->left = calculate_slab_order(cachep, size, flags | CFLGS_OBJFREELIST_SLAB);
   |   |   |   |      计算该kmem cache实例对应的slab order,原则是slab尽量小,浪费尽量少,详见重要函数分析。
   |   |   |   |      这里没有设置CFLGS_OFF_SLAB,是因为还没有创建freelist index的kmem cache实例,freelist 
   |   |   |   |      只能存放在slab内。
   |   |   |----->cachep->freelist_size = cachep->num * sizeof(freelist_idx_t);
   |   |   |      freelist index占用空间大小
   |   |   |----->err = setup_cpu_cache(cachep, gfp);
   |   |   |   |----->cachep->cpu_cache = alloc_kmem_cache_cpus(cachep, 1, 1);
   |   |   |   |      分配array_cache实例
   |   |   |   |----->set_up_node(kmem_cache, CACHE_CACHE);
   |   |   |   |      设置node
   |   |   |   |----->cpu_cache_get(cachep)->avail = 0;
   |   |   |   |      由于还没有申请slab,不存在可用的object,所以可用的object为0
   |----->list_add(&kmem_cache->list, &slab_caches);
   |      kmem cache实例加入slab_caches链表
   |----->slab_state = PARTIAL;
   |----->kmalloc_caches[INDEX_NODE] = create_kmalloc_cache("kmalloc-node",
   |                kmalloc_size(INDEX_NODE), ARCH_KMALLOC_FLAGS);
   |      创建第二个kmem cache实例,从object size可以看出,该实例用于为struct kmem_cache_node分配空间。
   |      指针数组kmalloc_caches是kmalloc用的kmem cache实例数组,该数组十分重要,详见重要变量分析。
   |   |----->struct kmem_cache *s = kmem_cache_zalloc(kmem_cache, GFP_NOWAIT);
   |   |      从kmem cache kmem_cache中分配一个object
   |   |   |----->return kmem_cache_alloc(k, flags | __GFP_ZERO);
   |   |   |   |----->void *ret = slab_alloc(cachep, flags, _RET_IP_);
   |   |   |   |   |----->objp = __do_cache_alloc(cachep, flags);
   |   |   |   |   |      分配一个object,该函数比较复杂,详情请参考重要函数分析
   |   |----->create_boot_cache(s, name, size, flags);
   |   |----->list_add(&s->list, &slab_caches);
   |----->slab_state = PARTIAL_NODE;
   |----->setup_kmalloc_cache_index_table();
   |----->init_list(kmem_cache, &init_kmem_cache_node[CACHE_CACHE + nid], nid);
   |   |----->ptr = kmalloc_node(sizeof(struct kmem_cache_node), GFP_NOWAIT, nodeid);
   |   |      分配struct kmem_cache_node
   |   |----->memcpy(ptr, list, sizeof(struct kmem_cache_node));
   |   |      将静态定义的struct kmem_cache_node拷贝到新分配的struct kmem_cache_node中
   |   |----->cachep->node[nodeid] = ptr;
   |----->init_list(kmalloc_cach
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值