搜索

15

主题

39

帖子

144

积分

注册会员

Rank: 2

积分
144
发表于 2014-10-25 23:20:03 5334 浏览 2 回复

【linux】【fs】【Dcache.c】vfs_caches_init初始化

【linux】【fs】【Dcache.c】vfs_caches_init初始化 虚拟文件初始化的文件中代码如下:
void __init vfs_caches_init(unsigned long mempages)
{
unsigned long reserve;
/* Base hash sizes on available memory, with a reserve equal to
           150% of current kernel size */
reserve = min((mempages - nr_free_pages()) * 3/2, mempages - 1);
mempages -= reserve;
names_cachep = kmem_cache_create("names_cache", PATH_MAX, 0,
   SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
dcache_init();
inode_init();
files_init(mempages);
mnt_init();
bdev_cache_init();
chrdev_init();
}

初始化的内容包括了dcache, inode, files, mnt, bdev,chrdev。每个初始化中大量使用了hash表。
static void __init dcache_init(void)
{
int loop;
/*
  * A constructor could be added for stable state like the lists,
  * but it is probably not worth it because of the cache nature
  * of the dcache.
  */
dentry_cache = KMEM_CACHE(dentry, SLAB_RECLAIM_ACCOUNT|SLAB_PANIC|SLAB_MEM_SPREAD);

register_shrinker(&dcache_shrinker);
/* Hash may have been set up in dcache_init_early */
if (!hashdist)
  return;
dentry_hashtable =  alloc_large_system_hash("Dentry cache", sizeof(struct hlist_bl_head), dhash_entries,
                       13,  0, &d_hash_shift,  &d_hash_mask, 0);

for (loop = 0; loop < (1 << d_hash_shift); loop++)
  INIT_HLIST_BL_HEAD(dentry_hashtable + loop);
}

void __init inode_init(void)
{
int loop;
/* inode slab cache */
inode_cachep = kmem_cache_create("inode_cache",
      sizeof(struct inode),
      0,
      (SLAB_RECLAIM_ACCOUNT|SLAB_PANIC|
      SLAB_MEM_SPREAD),
      init_once);
register_shrinker(&icache_shrinker);
/* Hash may have been set up in inode_init_early */
if (!hashdist)
  return;
inode_hashtable =
  alloc_large_system_hash("Inode-cache",
     sizeof(struct hlist_head),
     ihash_entries,
     14,
     0,
     &i_hash_shift,
     &i_hash_mask,
     0);

for (loop = 0; loop < (1 << i_hash_shift); loop++)
  INIT_HLIST_HEAD(&inode_hashtable[loop]);
}




回复

使用道具 举报

15

主题

39

帖子

144

积分

注册会员

Rank: 2

积分
144
 楼主| 发表于 2014-10-25 23:27:36
hash表展开后,看起来比较晦涩难懂啊

/*
* allocate a large system hash table from bootmem
* - it is assumed that the hash table must contain an exact power-of-2
*   quantity of entries
* - limit is the number of hash buckets, not the total allocation size
*/
void *__init alloc_large_system_hash(const char *tablename, unsigned long bucketsize,  unsigned long numentries,
                                                                                                                                       int scale, int flags,  unsigned int *_hash_shift,   unsigned int *_hash_mask,  unsigned long limit)
{
        unsigned long long max = limit;
        unsigned long log2qty, size;
        void *table = NULL;

        /* allow the kernel cmdline to have a say */
        if (!numentries)
        {
                /* round applicable memory size up to nearest megabyte */
                numentries = nr_kernel_pages;
                numentries += (1UL << (20 - PAGE_SHIFT)) - 1;
                numentries >>= 20 - PAGE_SHIFT;
                numentries <<= 20 - PAGE_SHIFT;

                /* limit to 1 bucket per 2^scale bytes of low memory */
                if (scale > PAGE_SHIFT)
                        numentries >>= (scale - PAGE_SHIFT);
                else
                        numentries <<= (PAGE_SHIFT - scale);

                /* Make sure we've got at least a 0-order allocation.. */
                if (unlikely(flags & HASH_SMALL))
                {
                        /* Makes no sense without HASH_EARLY */
                        WARN_ON(!(flags & HASH_EARLY));
                        if (!(numentries >> *_hash_shift))
                        {
                                numentries = 1UL << *_hash_shift;
                                BUG_ON(!numentries);
                        }
                }
                else if (unlikely((numentries * bucketsize) < PAGE_SIZE))
                        numentries = PAGE_SIZE / bucketsize;
        }
        numentries = roundup_pow_of_two(numentries);

        /* limit allocation size to 1/16 total memory by default */
        if (max == 0)
        {
                max = ((unsigned long long)nr_all_pages << PAGE_SHIFT) >> 4;
                do_div(max, bucketsize);
        }

        if (numentries > max)
                numentries = max;

        log2qty = ilog2(numentries);

        do
        {
                size = bucketsize << log2qty;
                if (flags & HASH_EARLY)
                        table = alloc_bootmem_nopanic(size);
                else if (hashdist)
                        table = __vmalloc(size, GFP_ATOMIC, PAGE_KERNEL);
                else
                {
                        /*
                         * If bucketsize is not a power-of-two, we may free
                         * some pages at the end of hash table which
                         * alloc_pages_exact() automatically does
                         */
                        if (get_order(size) < MAX_ORDER)
                        {
                                table = alloc_pages_exact(size, GFP_ATOMIC);
                                kmemleak_alloc(table, size, 1, GFP_ATOMIC);
                        }
                }
        } while (!table && size > PAGE_SIZE && --log2qty);

        if (!table)
                panic("Failed to allocate %s hash table\n", tablename);

        printk(KERN_INFO "%s hash table entries: %ld (order: %d, %lu bytes)\n",
                          tablename, (1UL << log2qty), ilog2(size) - PAGE_SHIFT, size);

        if (_hash_shift)
                *_hash_shift = log2qty;
        if (_hash_mask)
                *_hash_mask = (1 << log2qty) - 1;

        return table;
}
回复 点赞

使用道具 举报

48

主题

598

帖子

1923

积分

版主

Rank: 7Rank: 7Rank: 7

积分
1923
发表于 2014-11-24 14:24:47
厉害!
回复

使用道具 举报

返回列表
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

登录或注册

官方客服

QQ:2551456065

官方QQ群

195631883

扫一扫关注迅为公众号

群号652692981

 
快速回复 返回顶部 返回列表