在前文中介紹了slab所涉及到的數據結構, slab分配器的初始化工作都是圍繞這些數據結構來展開的,主要是針對以下兩個問題:
1.創建kmem_cache高速緩存用來存儲所有的cache描述符
2.創建array_cache和kmem_list3高速緩存用來存儲slab數據結構中的這兩個關鍵結構
這裡明顯有點自相矛盾,那就是slab管理器尚未建立起來,又如何靠slab分配高速緩存來給這些結構分配空間呢?
解決第一個問題的方法是直接靜態定義一個名為cache_cache的kmem_cache結構,來管理所有的kmem_cache描述符,對於array_cache和kmem_list3,內核也是先靜態定義,然後建立起普通高速緩存(general cache),再使用kmalloc分配普通高速緩存空間來替代之前靜態定義的部分。
相關閱讀:Linux Slab分配器(一)--概述 http://www.linuxidc.com/Linux/2012-06/62965.htm
普通高速緩存是一組大小按幾何倍數增長的高速緩存的合集,一個普通高速緩存用如下結構描述
- /* Size description struct for general caches. */
- struct cache_sizes {
- size_t cs_size; /*general cache的大小*/
- struct kmem_cache *cs_cachep; /*general cache的cache描述符指針*/
- #ifdef CONFIG_ZONE_DMA
- struct kmem_cache *cs_dmacachep;
- #endif
- };
普通高速緩存的大小由malloc_sizes表來確定
- /*
- * These are the default caches for kmalloc. Custom caches can have other sizes.
- */
- struct cache_sizes malloc_sizes[] = {
- #define CACHE(x) { .cs_size = (x) },
- #include <linux/kmalloc_sizes.h>
- CACHE(ULONG_MAX)
- #undef CACHE
- };
其中<linux/kmalloc_sizes.h>中的內容為
- #if (PAGE_SIZE == 4096)
- CACHE(32)
- #endif
- CACHE(64)
- #if L1_CACHE_BYTES < 64
- CACHE(96)
- #endif
- CACHE(128)
- #if L1_CACHE_BYTES < 128
- CACHE(192)
- #endif
- CACHE(256)
- CACHE(512)
- CACHE(1024)
- CACHE(2048)
- CACHE(4096)
- CACHE(8192)
- CACHE(16384)
- CACHE(32768)
- CACHE(65536)
- CACHE(131072)
- #if KMALLOC_MAX_SIZE >= 262144
- CACHE(262144)
- #endif
- #if KMALLOC_MAX_SIZE >= 524288
- CACHE(524288)
- #endif
- #if KMALLOC_MAX_SIZE >= 1048576
- CACHE(1048576)
- #endif
- #if KMALLOC_MAX_SIZE >= 2097152
- CACHE(2097152)
- #endif
- #if KMALLOC_MAX_SIZE >= 4194304
- CACHE(4194304)
- #endif
- #if KMALLOC_MAX_SIZE >= 8388608
- CACHE(8388608)
- #endif
- #if KMALLOC_MAX_SIZE >= 16777216
- CACHE(16777216)
- #endif
- #if KMALLOC_MAX_SIZE >= 33554432
- CACHE(33554432)
- #endif