dentry cache hash table size 지정은,
fs/dcache.c에서 alloc_large_system_hash를 통해서 된다. 그전에 dhash_entries는 kernel cmdline에서 지정하여 원하는 값을 패스 할 수 있다.
2965static void __init dcache_init(void) 2966{ 2967 int loop; 2968 2969 /* 2970 * A constructor could be added for stable state like the lists, 2971 * but it is probably not worth it because of the cache nature 2972 * of the dcache. 2973 */ 2974 dentry_cache = KMEM_CACHE(dentry, 2975 SLAB_RECLAIM_ACCOUNT|SLAB_PANIC|SLAB_MEM_SPREAD); 2976 2977 /* Hash may have been set up in dcache_init_early */ 2978 if (!hashdist) 2979 return; 2980 2981 dentry_hashtable = 2982 alloc_large_system_hash("Dentry cache", 2983 sizeof(struct hlist_bl_head), 2984 dhash_entries, 2985 13, 2986 0, 2987 &d_hash_shift, 2988 &d_hash_mask, 2989 0); 2990 2991 for (loop = 0; loop < (1 << d_hash_shift); loop++) 2992 INIT_HLIST_BL_HEAD(dentry_hashtable + loop); 2993}
그리고 만약 dhash_entries값이 0이면(전역비초기화 변수 이므로 0으로 되어 bss영역에 있을 것이다) 5395라인 하위로 타고 들어가, nr_kernel_pages에 기반을 둔 2의 배수를 설정하고 기타 log2작업(아 이건 나중에 보자...)을 통해 hash table size를 출력한다.
5381void *__init alloc_large_system_hash(const char *tablename, 5382 unsigned long bucketsize, 5383 unsigned long numentries, 5384 int scale, 5385 int flags, 5386 unsigned int *_hash_shift, 5387 unsigned int *_hash_mask, 5388 unsigned long limit) 5389{ 5390 unsigned long long max = limit; 5391 unsigned long log2qty, size; 5392 void *table = NULL; 5393 5394 /* allow the kernel cmdline to have a say */ 5395 if (!numentries) { 5396 /* round applicable memory size up to nearest megabyte */ 5397 numentries = nr_kernel_pages; 5398 numentries += (1UL << (20 - PAGE_SHIFT)) - 1; 5399 numentries >>= 20 - PAGE_SHIFT; 5400 numentries <<= 20 - PAGE_SHIFT; 5401 5402 /* limit to 1 bucket per 2^scale bytes of low memory */ 5403 if (scale > PAGE_SHIFT) 5404 numentries >>= (scale - PAGE_SHIFT); 5405 else 5406 numentries <<= (PAGE_SHIFT - scale); 5407 5408 /* Make sure we've got at least a 0-order allocation.. */ 5409 if (unlikely(flags & HASH_SMALL)) { 5410 /* Makes no sense without HASH_EARLY */ 5411 WARN_ON(!(flags & HASH_EARLY)); 5412 if (!(numentries >> *_hash_shift)) { 5413 numentries = 1UL << *_hash_shift; 5414 BUG_ON(!numentries); 5415 } 5416 } else if (unlikely((numentries * bucketsize) < PAGE_SIZE)) 5417 numentries = PAGE_SIZE / bucketsize; 5418 } 5419 numentries = roundup_pow_of_two(numentries); 5420 5421 /* limit allocation size to 1/16 total memory by default */ 5422 if (max == 0) { 5423 max = ((unsigned long long)nr_all_pages << PAGE_SHIFT) >> 4; 5424 do_div(max, bucketsize); 5425 } 5426 5427 if (numentries > max) 5428 numentries = max; 5429 5430 log2qty = ilog2(numentries); 5431 5432 do { 5433 size = bucketsize << log2qty; 5434 if (flags & HASH_EARLY) 5435 table = alloc_bootmem_nopanic(size); 5436 else if (hashdist) 5437 table = __vmalloc(size, GFP_ATOMIC, PAGE_KERNEL); 5438 else { 5439 /* 5440 * If bucketsize is not a power-of-two, we may free 5441 * some pages at the end of hash table which 5442 * alloc_pages_exact() automatically does 5443 */ 5444 if (get_order(size) < MAX_ORDER) { 5445 table = alloc_pages_exact(size, GFP_ATOMIC); 5446 kmemleak_alloc(table, size, 1, GFP_ATOMIC); 5447 } 5448 } 5449 } while (!table && size > PAGE_SIZE && --log2qty); 5450 5451 if (!table) 5452 panic("Failed to allocate %s hash table\n", tablename); 5453 5454 printk(KERN_INFO "%s hash table entries: %ld (order: %d, %lu bytes)\n", 5455 tablename, 5456 (1UL << log2qty), 5457 ilog2(size) - PAGE_SHIFT, 5458 size); 5459 5460 if (_hash_shift) 5461 *_hash_shift = log2qty; 5462 if (_hash_mask) 5463 *_hash_mask = (1 << log2qty) - 1; 5464 5465 return table; 5466}
'리눅스 > 커널' 카테고리의 다른 글
커널 디버깅 방법 (0) | 2014.09.19 |
---|---|
syslog LOCAL7 (0) | 2014.08.28 |
Memory 정보 출력되는 곳 (0) | 2014.04.07 |
driver 초기화 시에 쓰이는 module_init (0) | 2014.04.04 |
Machine 이름 바꾸기 (0) | 2014.04.03 |