2085 /**
2086 * kmem_cache_create - 创建一个 cache.
2087 * @name: 此cache在/proc/slabinfo中显示的名字
2088 * @size: 此cache中每个对象的大小
2089 * @align: 对象对齐方式
2090 * @flags: SLAB 标志
2091 * @ctor: 对象构造函数.
2092 * @dtor: 对象析构函数.
2093 *
2094 * 成功返回cache的指针,失败返回NULL.
2095 * 此函数不能在中断中调用,但能被中断.
2096 * @ctor 将在cache建立新页面时候调用
2097 * @dtor 将在页面被回收时候调用.
2098 *
2099 * @name must be valid until the cache is destroyed. This implies that
2100 * the module calling this has to destroy the cache before getting unloaded.
2101 *
2102 * The flags are
2103 *
2104 * %SLAB_POISON - Poison the slab with a known test pattern (a5a5a5a5)
2105 * to catch references to uninitialised memory.
2106 *
2107 * %SLAB_RED_ZONE - Insert `Red' zones around the allocated memory to check
2108 * for buffer overruns.
2109 *
2110 * %SLAB_HWCACHE_ALIGN - 硬件对齐Align the objects in this cache to a hardware
2111 * cacheline. This can be beneficial if you're counting cycles as closely
2112 * as davem.
2113 */
2114 struct kmem_cache *
2115 kmem_cache_create (const char *name, size_t size, size_t align,
2116 unsigned long flags,
2117 void (*ctor)(void*, struct kmem_cache *, unsigned long),
2118 void (*dtor)(void*, struct kmem_cache *, unsigned long))
2119 {
2120 size_t left_over, slab_size, ralign;
2121 struct kmem_cache *cachep = NULL, *pc;
2122
2123 /*
2124 * 参数检查.
2125 */
2126 if (!name || in_interrupt() || (size < BYTES_PER_WORD) ||
2127 (size > (1 << MAX_OBJ_ORDER) * PAGE_SIZE) || (dtor && !ctor)) {
2128 printk(KERN_ERR "%s: Early error in slab %s\n", __FUNCTION__,
2129 name);
2130 BUG();
2131 }
2132
2133 /*
2134 * We use cache_chain_mutex to ensure a consistent view of
2135 * cpu_online_map as well. Please see cpuup_callback
2136 */
2137 mutex_lock(&cache_chain_mutex);//互斥假锁
2138//遍历列表,检查此名字cache是否已经建立
2139 list_for_each_entry(pc, &cache_chain, next) {
2140 char tmp;
2141 int res;
2142
2143 /*
2144 * 当一个module卸载后没有销毁其slab cache且不会被复用时候,打印一个警告信息
2147 */
2148 res = probe_kernel_address(pc->name, tmp);
2149 if (res) {
2150 printk("SLAB: cache with size %d has lost its name\n",
2151 pc->buffer_size);
2152 continue;
2153 }
2154
2155 if (!strcmp(pc->name, name)) {
2156 printk("kmem_cache_create: duplicate cache %s\n", name);
2157 dump_stack();
2158 goto oops;
2159 }
2160 }
2161
2162 //调式部分略去
2185 if (flags & SLAB_DESTROY_BY_RCU)
2186 BUG_ON(dtor);
2187
2188 /*
2189 * Always checks flags, a caller might be expecting debug support which
2190 * isn't available.
2191 */
2192 BUG_ON(flags & ~CREATE_MASK);
2193
2194 /*
2195 * Check that size is in terms of words. This is needed to avoid
2196 * unaligned accesses for some archs when redzoning is used, and makes
2197 * sure any on-slab bufctl's are also correctly aligned.
2198 */
// #define BYTES_PER_WORD sizeof(void *)
2199 if (size & (BYTES_PER_WORD - 1)) {
2200 size += (BYTES_PER_WORD - 1);
2201 size &= ~(BYTES_PER_WORD - 1);
2202 }
2203
2204 /* 计算buffer的对齐量 */
2205
2206 /* 1) 不同架构对齐对齐方式*/
2207 if (flags & SLAB_HWCACHE_ALIGN) {
2208 /*
2209 * 默认对齐方式: 在各自体系架构代码中定义.
2210 * 例外:对象很小以至能在一个cacheline中放下几个对象
2212 */
2213 ralign = cache_line_size();//取得具体体系架构cacheline大小
2214 while (size <= ralign / 2)
2215 ralign /= 2;//当对象小于二分之一cacheline的时候计算具体对齐量
2216 } else {
2217 ralign = BYTES_PER_WORD;//在I386上为4BYTE对齐
2218 }
2219
2220 /*
2221 * Redzoning and user store require word alignment. Note this will be
2222 * overridden by architecture or caller mandated alignment if either
2223 * is greater than BYTES_PER_WORD.
2224 */
2225 if (flags & SLAB_RED_ZONE || flags & SLAB_STORE_USER)
2226 ralign = BYTES_PER_WORD;
2227
2228 /* 2) 体系架构对齐 */
2229 if (ralign < ARCH_SLAB_MINALIGN) {
2230 ralign = ARCH_SLAB_MINALIGN;
2231 }
2232 /* 3) 调用者指定对齐 */
2233 if (ralign < align) {
2234 ralign = align;
2235 }
2236 /* 如果需要关掉调试 */
2237 if (ralign > BYTES_PER_WORD)
2238 flags &= ~(SLAB_RED_ZONE | SLAB_STORE_USER);
2242 align = ralign;
2243
2244 /* 分配一个kmem_cache并以0初始化 */
2245 cachep = kmem_cache_zalloc(&cache_cache, GFP_KERNEL);
2246 if (!cachep)
2247 goto oops;
2248
2249 //调式部分略去
2276 /*
2277 * Determine if the slab management is 'on' or 'off' slab.
2278 * (bootstrapping cannot cope with offslab caches so don't do
2279 * it too early on.)
2280 */
2281 if ((size >= (PAGE_SIZE >> 3)) && !slab_early_init)
2282 /*
2283 * 如果比较大,最好把slab与对象分开存储
2285 */
2286 flags |= CFL.GS_OFF_SLAB;
2287
2288 size = ALIGN(size, align);//对齐后对象大小
2289//计算slab需要page数量,slab中对象个数,以及对齐后剩余量
2290 left_over = calculate_slab_order(cachep, size, align, flags);
2291
2292 if (!cachep->num) {
2293 printk("kmem_cache_create: couldn't create cache %s.\n", name);
2294 kmem_cache_free(&cache_cache, cachep);
2295 cachep = NULL;
2296 goto oops;
2297 }
//计算slab数据结构对齐后需要空间大小,对象个数在calculate_slab_order计算出来
2298 slab_size = ALIGN(cachep->num * sizeof(kmem_bufctl_t)
2299 + sizeof(struct slab), align);
2300
2301 /*
2302 * 如果设置了off-slab, 但是我们有足够空间将slab与对象存放一起,
2303 * 把off-slab改为on-slab一起存放。(空间节省考虑)
2304 */
2305 if (flags & CFL.GS_OFF_SLAB && left_over >= slab_size) {
2306 flags &= ~CFL.GS_OFF_SLAB;
2307 left_over -= slab_size;
2308 }
2309
2310 if (flags & CFL.GS_OFF_SLAB) {
2311 /* 确实独立存放slab结构. 没必要手工对齐(因为在那边是一个对象,早已经对齐)*/
2312 slab_size =
2313 cachep->num * sizeof(kmem_bufctl_t) + sizeof(struct slab);
2314 }
2315
2316 cachep->colour_off = cache_line_size();
2317 // colour_off其实是对齐的最小单位
2318 if (cachep->colour_off < align)
2319 cachep->colour_off = align;
//color是页面中剩余空间除以对齐单位
2320 cachep->colour = left_over / cachep->colour_off;
2321 cachep->slab_size = slab_size;//slab结构的大小(和对象没关系)
2322 cachep->flags = flags;//下面开始就是设置标志位了
2323 cachep->gfpflags = 0;
2324 if (flags & SLAB_CACHE_DMA)//设置DMA标志
2325 cachep->gfpflags |= GFP_DMA;
2326 cachep->buffer_size = size; //对齐后一个对象大小
2327 cachep->reciprocal_buffer_size = reciprocal_value(size);
2328
2329 if (flags & CFL.GS_OFF_SLAB) {
//如果slab结构独立存放,还需要在通用cache中找到对应大小的slab,作为一个对象存入
2330 cachep->slabp_cache = kmem_find_general_cachep(slab_size, 0u);
2331 /*
2332 * This is a possibility for one of the malloc_sizes caches.
2333 * But since we go off slab only for object size greater than
2334 * PAGE_SIZE/8, and malloc_sizes gets created in ascending order,
2335 * this should not happen at all.
2336 * But leave a BUG_ON for some lucky dude.
2337 */
2338 BUG_ON(!cachep->slabp_cache);
2339 }
2340 cachep->ctor = ctor;
2341 cachep->dtor = dtor;
2342 cachep->name = name;
2343//设置一些多处理器相关变量
2344 if (setup_cpu_cache(cachep)) {
2345 __kmem_cache_destroy(cachep);
2346 cachep = NULL;
2347 goto oops;
2348 }
2349
2350 /* cache setup completed, link it into the list */
2351 list_add(&cachep->next, &cache_chain);//加入cache_chain的链表
2352 oops:
2353 if (!cachep && (flags & SLAB_PANIC))
2354 panic("kmem_cache_create(): failed to create slab `%s'\n",
2355 name);
2356 mutex_unlock(&cache_chain_mutex);
2357 return cachep;
2358 }
2359 EXPORT_SYMBOL(kmem_cache_create);
Trackback: http://tb.donews.net/TrackBack.aspx?PostId=1177944