前沿
本文只讨论slub下的kmalloc机制。
kmalloc在哪定义? slab.h
KMALLOC_MAX_CACHE_SIZE是多大? 4KB
大于4KB的内存需求kmalloc用什么分配?
if (size > 4KB)
return kmalloc_large(size, flags);
具体流程:
alloc_pages 直接从伙伴系统拿
|-kmalloc(size_t size, gfp_t flags)
|----kmalloc_large(size, flags);
|-------get_order(size);
|-------alloc_pages(flags, order);
小于4KB的内存需求kmalloc用什么分配?
从kmalloc cache中分配,kmalloc cache是多个slab节点的kmem cache
详细参考文章:《【1000个Linux内存知识-013】-关于kmalloc分配内存使用的kmalloc cache的全局表kmalloc_caches和kc名字表kmalloc_info》
简单信息如下:
关于kmalloc_caches
kmalloc_caches是一个二维数组指针:
第一维 总的3个类型(nomal reclaim dma)
第二维 每类13个(page_order+1) kmem_cache,每个kmem_cache是负责一些数据大小的内存分配,比如小于8字节的就在第三个kmem_cache(具体待研究)
三种kmalloc cache的数量:
graph LR
3种kmalloc cache --> KMALLOC_NORMAL
3种kmalloc cache --> KMALLOC_RECLAIM
3种kmalloc cache --> KMALLOC_DMA
关于kmalloc_cache中每类13个kmem_cache与实际需要分配的size大小的对应关系
每个kmem_cache是负责一些数据大小的内存分配,比如小于8字节的就在第三个。
size_index表示 size对应的index的mapping获取,只是size_index进行了8个字节的压缩。也就是1-8是同一个mapping。
为什么找一个size对应的kmem_cache要整这么麻烦?
为什么要按照192进行区隔开?
以后完善。
kmalloc具体分配小于4K的流程
|-kmalloc(size_t size, gfp_t flags)
|----__kmalloc(size_t size, gfp_t flags) //小于4KB
|-------kmalloc_large(size, flags);
|-----------struct kmem_cache *s = kmalloc_slab(size, flags); //获取slab cache
|-----------slab_alloc(s, flags, _RET_IP_); 分配
可以看到主要原理就是通过size找到对应的kmem_cache,然后用slab_alloc从cache中分配内存。
slab的四部曲create destory alloc free参考其他文章
综述
- 内核中kmalloc根据size大小选择不同分配器,小于4K从kmalloc cache,大于4K从伙伴系统
- kmalloc cache是从slab预分配的零售商,有3*13-39个kmem cache,kmalloc根据size大小决定使用哪个kmem cache
- kmalloc的cache类型是kmem cache,存在kmalloc_caches全局表中
- kmalloc_caches表每个slab对象kmem cache里面的obj大小相似,比如kmalloc-8都是1-8大小的内存块。
- kmalloc不全是从slab分配,也会从伙伴直接分配