Skip to content

Latest commit

 

History

History
1001 lines (824 loc) · 29.1 KB

a10c_119.md

File metadata and controls

1001 lines (824 loc) · 29.1 KB
ARM10C : 119 주차
일시 : 2015.10.10 (119 주차 스터디 진행)
모임명 : NAVER_개발자커뮤니티지원_10차ARM-C
장소 : 토즈 타워점
장소지원 : NAVER 개발자 커뮤니티 지원 프로그램
참여인원 : 3명

============

119 주차 진도

  • 10월 03일 진도로 다시 복습을 했습니다.

  • proc_caches_init()

  • sighand_struct, signal_struct, files_struct, fs_struct, mm_struct, vm_area_struct, nsproxy
  • 를 사용하기 위한 kmem_cache 할당자 및 percpu list 초기화 수행
  • buffer_init()부터 소스 코드 분석을 계속했습니다.

  • buffer_init()

  • buffer_head 를 사용하기 위한 kmem_cache 할당자 및 max_buffer_heads 값 초기화 수행
  • key_init()
  • null funtion()
  • security_init()
  • null funtion()
  • dbg_late_init()
  • null funtion()
  • vfs_caches_init()

main.c::start_kernel()

// ARM10C 20130824
asmlinkage void __init start_kernel(void)
{
	char * command_line;
	extern const struct kernel_param __start___param[], __stop___param[];
	// ATAG,DTB 정보로 사용
...

	anon_vma_init();
	// anon vma 를 사용하기 위한 kmem_cache 할당자 초기화 수행

	thread_info_cache_init(); // null function
	cred_init();
	// credentials 를 사용하기 위한 kmem_cache 할당자 초기화 수행

	// totalram_pages: 총 free된 page 수
	fork_init(totalram_pages);
	// task_struct 를 사용하기 위한 kmem_cache 할당자 초기화 수행
	// max_threads값을 계산하여 init_task에 threads값의 limit 값 설정함

	proc_caches_init();
	// sighand_struct, signal_struct, files_struct, fs_struct, mm_struct, vm_area_struct, nsproxy
	// 를 사용하기 위한 kmem_cache 할당자 및 percpu list 초기화 수행
	
	buffer_init();

buffer.c::buffer_init()

  • call :
  • start_kernel()->buffer_init()
  • buffer_head 를 할당합니다.
// ARM10C 20151003
void __init buffer_init(void)
{
	unsigned long nrpages;

	// sizeof(struct buffer_head): 56 bytes,
	// SLAB_RECLAIM_ACCOUNT: 0x00020000UL, SLAB_PANIC: 0x00040000UL, SLAB_DESTROY_BY_RCU: 0x00080000UL
	// kmem_cache_create("buffer_head", 56, 0, 0xE0000, NULL): kmem_cache#7
	bh_cachep = kmem_cache_create("buffer_head",
			sizeof(struct buffer_head), 0,
				(SLAB_RECLAIM_ACCOUNT|SLAB_PANIC|
				SLAB_MEM_SPREAD),
				NULL);
// ARM10C 20151003
// "buffer_head", sizeof(struct buffer_head): 56 bytes, 0, 0x000E0000, NULL
struct kmem_cache *
kmem_cache_create(const char *name, size_t size, size_t align,
		  unsigned long flags, void (*ctor)(void *))
{
	// name: "buffer_head", size: 56, align: 0, flags: 0xE0000, ctor: NULL
	// kmem_cache_create_memcg(NULL, "buffer_head", 56, 0, 0xE0000, NULL): kmem_cache#7
	return kmem_cache_create_memcg(NULL, name, size, align, flags, ctor, NULL);
	// bh_cachep: kmem_cache#7
}
// ARM10C 20151003
void __init buffer_init(void)
{
	unsigned long nrpages;

	// sizeof(struct buffer_head): 56 bytes,
	// SLAB_RECLAIM_ACCOUNT: 0x00020000UL, SLAB_PANIC: 0x00040000UL, SLAB_DESTROY_BY_RCU: 0x00080000UL
	// kmem_cache_create("buffer_head", 56, 0, 0xE0000, NULL): kmem_cache#7
	bh_cachep = kmem_cache_create("buffer_head",
			sizeof(struct buffer_head), 0,
				(SLAB_RECLAIM_ACCOUNT|SLAB_PANIC|
				SLAB_MEM_SPREAD),
				NULL);
    // bh_cachep: kmem_cache#7

	/*
	 * Limit the bh occupancy to 10% of ZONE_NORMAL
	 */
	// nr_free_buffer_pages(): 0x7f7d6
	nrpages = (nr_free_buffer_pages() * 10) / 100;
  • start_kernel()->buffer_init()->nr_free_zone_pages()
// ARM10C 20151003
unsigned long nr_free_buffer_pages(void)
{
	// NOTE:
	// nr_free_zone_pages(0): 0x7f7d6 값은 정확한 값이 아님
	// 이전의 주석 결과 값을 이용하여 진행함

	// GFP_USER: 0x200D0, gfp_zone(0x200D0): 0
	// nr_free_zone_pages(0): 0x7f7d6
	return nr_free_zone_pages(gfp_zone(GFP_USER));
}
EXPORT_SYMBOL_GPL(nr_free_buffer_pages);
  • start_kernel()->buffer_init()->nr_free_zone_pages()->nr_free_zone_pages()
// ARM10C 20151003
// 0
static unsigned long nr_free_zone_pages(int offset)
{
	struct zoneref *z;
	struct zone *zone;

	/* Just pick one node, since fallback list is circular */
	unsigned long sum = 0;

	// numa_node_id(): 0, GFP_KERNEL: 0xD0
	struct zonelist *zonelist = node_zonelist(numa_node_id(), GFP_KERNEL);
	// zonelist: contig_page_data->node_zonelists

	// zonelist: contig_page_data->node_zonelists, offset: 0
	for_each_zone_zonelist(zone, z, zonelist, offset) {
	// for (z = first_zones_zonelist(contig_page_data->node_zonelists, 0, 0, &zone);
	//          zone; z = next_zones_zonelist(++z, 0, 0, &zone))
		// [1st] z: contig_page_data->node_zonelists->_zonerefs[1]
		// [1st] zone: contig_page_data->node_zones[0]
		// [2nd] z: contig_page_data->node_zonelists->_zonerefs[0]
		// [2nd] zone: contig_page_data->node_zones[1]

		// [1st]: zone->managed_pages: contig_page_data->node_zones[0]->managed_pages: 0x2efd6
		// [2nd]: zone->managed_pages: contig_page_data->node_zones[1]->managed_pages: 0x50800
		unsigned long size = zone->managed_pages;
		// [1st]: size: 0x2efd6
		// [2nd]: size: 0x50800

		// [1st] zone: contig_page_data->node_zones[0]
		// [1st] high_wmark_pages(contig_page_data->node_zones[0]): 0
		// [2st] zone: contig_page_data->node_zones[1]
		// [2st] high_wmark_pages(contig_page_data->node_zones[1]): 0
		unsigned long high = high_wmark_pages(zone);
		// [1st]: high: 0
		// [2nd]: high: 0

		// [1st]: size: 0x2efd6
		// [2nd]: size: 0x50800
		if (size > high)
			// [1st] sum: 0
			// [2nd]: sum: 0x2efd6
			sum += size - high;
			// [1st]: sum: 0x2efd6
			// [2nd]: sum: 0x7f7d6
	}

	// sum: 0x7f7d6
	return sum;
	// return 0x7f7d6
}
// ARM10C 20151003
unsigned long nr_free_buffer_pages(void)
{
	// NOTE:
	// nr_free_zone_pages(0): 0x7f7d6 값은 정확한 값이 아님
	// 이전의 주석 결과 값을 이용하여 진행함

	// GFP_USER: 0x200D0, gfp_zone(0x200D0): 0
	// nr_free_zone_pages(0): 0x7f7d6
	return nr_free_zone_pages(gfp_zone(GFP_USER));
	// return 0x7f7d6
}
EXPORT_SYMBOL_GPL(nr_free_buffer_pages);
  • hotcpu_notifier()
// ARM10C 20151003
void __init buffer_init(void)
{
	unsigned long nrpages;

	// sizeof(struct buffer_head): 56 bytes,
	// SLAB_RECLAIM_ACCOUNT: 0x00020000UL, SLAB_PANIC: 0x00040000UL, SLAB_DESTROY_BY_RCU: 0x00080000UL
	// kmem_cache_create("buffer_head", 56, 0, 0xE0000, NULL): kmem_cache#7
	bh_cachep = kmem_cache_create("buffer_head",
			sizeof(struct buffer_head), 0,
				(SLAB_RECLAIM_ACCOUNT|SLAB_PANIC|
				SLAB_MEM_SPREAD),
				NULL);
	// bh_cachep: kmem_cache#7

	/*
	 * Limit the bh occupancy to 10% of ZONE_NORMAL
	 */
	// nr_free_buffer_pages(): 0x7f7d6
	nrpages = (nr_free_buffer_pages() * 10) / 100;
	// nrpages: 0xcbfb

	// nrpages: 0xcbfb, PAGE_SIZE: 0x1000, sizeof(struct buffer_head): 56 bytes
	max_buffer_heads = nrpages * (PAGE_SIZE / sizeof(struct buffer_head));
	// max_buffer_heads: 0x3a2a93

	hotcpu_notifier(buffer_cpu_notify, 0);
// ARM10C 20151003
// buffer_cpu_notify, 0
#define hotcpu_notifier(fn, pri)	cpu_notifier(fn, pri)
// ARM10C 20151003
// cpu_notifier(buffer_cpu_notify, 0):
// {
// 	static struct notifier_block buffer_cpu_notify_nb =
//      { .notifier_call = buffer_cpu_notify, .priority = 0 };
// 	register_cpu_notifier(&buffer_cpu_notify_nb);
// }
#define cpu_notifier(fn, pri) {					\
	static struct notifier_block fn##_nb =			\
		{ .notifier_call = fn, .priority = pri };	\
	register_cpu_notifier(&fn##_nb);			\
}
// ARM10C 20151003
// &buffer_cpu_notify_nb
int __ref register_cpu_notifier(struct notifier_block *nb)
{
	int ret;
	cpu_maps_update_begin();
	// waiter를 만들어 mutex를 lock을 시도하며 기다리다 가능할 때 mutex lock한다.

	// &cpu_chain, nb: &hotplug_cfd_notifier
	// raw_notifier_chain_register(&cpu_chain, &hotplug_cfd_notifier): 0
	//
	// &cpu_chain, nb: &buffer_cpu_notify_nb
	// raw_notifier_chain_register(&cpu_chain, &buffer_cpu_notify_nb): 0
	ret = raw_notifier_chain_register(&cpu_chain, nb);
	// ret: 0


	// raw_notifier_chain_register(&buffer_cpu_notify_nb) 에서 한일:
	//
	// (&cpu_chain)->head: &buffer_cpu_notify_nb
	// (&buffer_cpu_notify_nb)->next은 (&hotplug_cfd_notifier)->next로 대입

	cpu_maps_update_done();
	// mutex를 기다리는(waiter)가 있으면 깨우고 아니면 mutex unlock한다.

	// ret: 0
	return ret;
	// return 0
}
  • hotcpu_notifier 에서 한일:
  • (&cpu_chain)->head: &buffer_cpu_notify_nb
  • (&buffer_cpu_notify_nb)->next은 (&hotplug_cfd_notifier)->next로 대입

start_kernel()

  • return buffer_init()
// ARM10C 20130824
asmlinkage void __init start_kernel(void)
{
	char * command_line;
	extern const struct kernel_param __start___param[], __stop___param[];
	// ATAG,DTB 정보로 사용

...

	cred_init();
	// credentials 를 사용하기 위한 kmem_cache 할당자 초기화 수행

	// totalram_pages: 총 free된 page 수
	fork_init(totalram_pages);
	// task_struct 를 사용하기 위한 kmem_cache 할당자 초기화 수행
	// max_threads값을 계산하여 init_task에 threads값의 limit 값 설정함

	proc_caches_init();
	// sighand_struct, signal_struct, files_struct, fs_struct, mm_struct, vm_area_struct, nsproxy
	// 를 사용하기 위한 kmem_cache 할당자 및 percpu list 초기화 수행

	buffer_init();
	// buffer_head 를 사용하기 위한 kmem_cache 할당자 및 max_buffer_heads 값 초기화 수행
  • key_init()
// ARM10C 20151003
#define key_init()			do { } while(0)
  • security_init()
// ARM10C 20151003
static inline int security_init(void)
{
	return 0;
}
  • dbg_late_init()
// ARM10C 20151003
#define dbg_late_init()
// ARM10C 20130824
asmlinkage void __init start_kernel(void)
{
	char * command_line;
	extern const struct kernel_param __start___param[], __stop___param[];
	// ATAG,DTB 정보로 사용

...

	cred_init();
	// credentials 를 사용하기 위한 kmem_cache 할당자 초기화 수행

	// totalram_pages: 총 free된 page 수
	fork_init(totalram_pages);
	// task_struct 를 사용하기 위한 kmem_cache 할당자 초기화 수행
	// max_threads값을 계산하여 init_task에 threads값의 limit 값 설정함

	proc_caches_init();
	// sighand_struct, signal_struct, files_struct, fs_struct, mm_struct, vm_area_struct, nsproxy
	// 를 사용하기 위한 kmem_cache 할당자 및 percpu list 초기화 수행

	buffer_init();
	// buffer_head 를 사용하기 위한 kmem_cache 할당자 및 max_buffer_heads 값 초기화 수행

	key_init(); // null funtion
	security_init(); // null funtion
	dbg_late_init(); // null funtion

	// totalram_pages: 총 free된 page 수
    vfs_caches_init(totalram_pages);

dcache.c:vfs_caches_init()

  • call
  • start_kerne()->vfs_caches_init()
  • name_cache를 할당받음
// ARM10C 20151003
// totalram_pages: 총 free된 page 수
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 */

	// NOTE:
	// mempages 값과 nr_free_pages() 의 값을 정확히 알 수 없음
	// 계산된 reserve의 값을 XXX 로 함

	// mempages: 총 free된 page 수, nr_free_pages(): 현재의 free pages 수
	reserve = min((mempages - nr_free_pages()) * 3/2, mempages - 1);
	// reserve: XXX

	// mempages: 총 free된 page 수, reserve: XXX
	mempages -= reserve;
	// mempages: 총 free된 page 수 - XXX

	// PATH_MAX: 4096
	// SLAB_HWCACHE_ALIGN: 0x00002000UL, SLAB_PANIC: 0x00040000UL
	// kmem_cache_create("names_cache", 4096, 0, 0x42000, NULL): kmem_cache#6
	names_cachep = kmem_cache_create("names_cache", PATH_MAX, 0,
			SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
// ARM10C 20151003
// "names_cache", 4096, 0, 0x42000, NULL
struct kmem_cache *
kmem_cache_create(const char *name, size_t size, size_t align,
		  unsigned long flags, void (*ctor)(void *))
{
	// name: "names_cache", size: 4096, align: 0, flags: 0x42000, ctor: NULL
	// kmem_cache_create_memcg(NULL, "names_cache", 4096, 0, 0x42000, NULL): kmem_cache#6
	return kmem_cache_create_memcg(NULL, name, size, align, flags, ctor, NULL);
	// return kmem_cache#6
}
  • dcache_init()
// ARM10C 20151003
// totalram_pages: 총 free된 page 수
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 */

	// NOTE:
	// mempages 값과 nr_free_pages() 의 값을 정확히 알 수 없음
	// 계산된 reserve의 값을 XXX 로 함

	// mempages: 총 free된 page 수, nr_free_pages(): 현재의 free pages 수
	reserve = min((mempages - nr_free_pages()) * 3/2, mempages - 1);
	// reserve: XXX

	// mempages: 총 free된 page 수, reserve: XXX
	mempages -= reserve;
	// mempages: 총 free된 page 수 - XXX

	// PATH_MAX: 4096
	// SLAB_HWCACHE_ALIGN: 0x00002000UL, SLAB_PANIC: 0x00040000UL
	// kmem_cache_create("names_cache", 4096, 0, 0x42000, NULL): kmem_cache#6
	names_cachep = kmem_cache_create("names_cache", PATH_MAX, 0,
			SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
	// names_cachep: kmem_cache#6

	dcache_init();

dcache.c::dcache_init()

  • call
  • start_kerne()->vfs_caches_init()
    • kmem_cache_create(); // names_cache
    • dcache_init()
  • dentry를 할당 받는다.
// ARM10C 20151003
static void __init dcache_init(void)
{
	unsigned 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. 
	 */
	// sizeof(struct dentry): 140 bytes
	// SLAB_RECLAIM_ACCOUNT: 0x00020000UL, SLAB_PANIC: 0x00040000UL, SLAB_MEM_SPREAD: 0x00100000UL
	// KMEM_CACHE(dentry, 0x160000):
	// kmem_cache_create("dentry", sizeof(struct dentry), __alignof__(struct dentry), (0x160000), NULL): kmem_cache#5
	dentry_cache = KMEM_CACHE(dentry,
		SLAB_RECLAIM_ACCOUNT|SLAB_PANIC|SLAB_MEM_SPREAD);
// ARM10C 20151003
// #define KMEM_CACHE(dentry, 0x160000):
// kmem_cache_create("dentry", sizeof(struct dentry), __alignof__(struct dentry), (0x160000), NULL)
#define KMEM_CACHE(__struct, __flags) kmem_cache_create(#__struct,\
		sizeof(struct __struct), __alignof__(struct __struct),\
		(__flags), NULL)
// ARM10C 20151003
// "dentry", sizeof(struct dentry): 140 bytes, __alignof__(struct dentry): 4, (0x160000), NULL
struct kmem_cache *
kmem_cache_create(const char *name, size_t size, size_t align,
		  unsigned long flags, void (*ctor)(void *))
{
	// name: "dentry", size: 140, align: 4, flags: 0x160000, ctor: NULL
	// kmem_cache_create_memcg(NULL, "dentry", 140, 4, 0x160000, NULL): kmem_cache#5
	return kmem_cache_create_memcg(NULL, name, size, align, flags, ctor, NULL);
	// return kmem_cache#5
}
  • hashdist에서 리턴함.
// ARM10C 20151003
static void __init dcache_init(void)
{
	unsigned 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. 
	 */
	// sizeof(struct dentry): 140 bytes
	// SLAB_RECLAIM_ACCOUNT: 0x00020000UL, SLAB_PANIC: 0x00040000UL, SLAB_MEM_SPREAD: 0x00100000UL
	// KMEM_CACHE(dentry, 0x160000):
	// kmem_cache_create("dentry", sizeof(struct dentry), __alignof__(struct dentry), (0x160000), NULL): kmem_cache#5
	dentry_cache = KMEM_CACHE(dentry,
		SLAB_RECLAIM_ACCOUNT|SLAB_PANIC|SLAB_MEM_SPREAD);
	// dentry_cache: kmem_cache#5

	/* Hash may have been set up in dcache_init_early */
	// hashdist: 0
	if (!hashdist)
		return;
		// 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,
					0);

	for (loop = 0; loop < (1U << d_hash_shift); loop++)
		INIT_HLIST_BL_HEAD(dentry_hashtable + loop);
}
  • dcache_init에서 한일:
  • struct dentry를 위한 kmem_cache 생성
  • dentry_cache: kmem_cache#5

dcache.c::vfs_caches_init()

  • call
  • start_kerne()->vfs_caches_init()
    • kmem_cache_create(); // names_cache
    • dcache_init()
    • inode_init()
// ARM10C 20151003
// totalram_pages: 총 free된 page 수
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 */

	// NOTE:
	// mempages 값과 nr_free_pages() 의 값을 정확히 알 수 없음
	// 계산된 reserve의 값을 XXX 로 함

	// mempages: 총 free된 page 수, nr_free_pages(): 현재의 free pages 수
	reserve = min((mempages - nr_free_pages()) * 3/2, mempages - 1);
	// reserve: XXX

	// mempages: 총 free된 page 수, reserve: XXX
	mempages -= reserve;
	// mempages: 총 free된 page 수 - XXX

	// PATH_MAX: 4096
	// SLAB_HWCACHE_ALIGN: 0x00002000UL, SLAB_PANIC: 0x00040000UL
	// kmem_cache_create("names_cache", 4096, 0, 0x42000, NULL): kmem_cache#6
	names_cachep = kmem_cache_create("names_cache", PATH_MAX, 0,
			SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
	// names_cachep: kmem_cache#6

	dcache_init();

	// dcache_init에서 한일:
	//
	// struct dentry를 위한 kmem_cache 생성
	// dentry_cache: kmem_cache#5

	inode_init();

inode.c::inode_init()

  • call
  • start_kerne()->vfs_caches_init()
    • kmem_cache_create(); // names_cache
    • dcache_init()
    • inode_init()
  • inode_cache를 할당받는다.
// ARM10C 20151003
void __init inode_init(void)
{
	unsigned int loop;

	/* inode slab cache */
	// sizeof(struct inode): 394 bytes,
	// SLAB_RECLAIM_ACCOUNT: 0x00020000UL, SLAB_PANIC: 0x00040000UL, SLAB_MEM_SPREAD: 0x00100000UL,
	// kmem_cache_create("inode_cache", 394, 0, 0x160000, init_once): kmem_cache#4
	inode_cachep = kmem_cache_create("inode_cache",
					 sizeof(struct inode),
					 0,
					 (SLAB_RECLAIM_ACCOUNT|SLAB_PANIC|
					 SLAB_MEM_SPREAD),
					 init_once);
// ARM10C 20151003
// "inode_cache", sizeof(struct inode): 394 bytes, 0, 0x160000, init_once
struct kmem_cache *
kmem_cache_create(const char *name, size_t size, size_t align,
		  unsigned long flags, void (*ctor)(void *))
{
	// name: "inode_cache", size: 394, align: 0, flags: 0x160000, ctor: init_once
	// kmem_cache_create_memcg(NULL, "inode_cache", 394, 4, 0x160000, init_once): kmem_cache#4
	return kmem_cache_create_memcg(NULL, name, size, align, flags, ctor, NULL);
	// return kmem_cache#4
}
  • hashdist에서 리턴한다.
// ARM10C 20151003
void __init inode_init(void)
{
	unsigned int loop;

	/* inode slab cache */
	// sizeof(struct inode): 394 bytes,
	// SLAB_RECLAIM_ACCOUNT: 0x00020000UL, SLAB_PANIC: 0x00040000UL, SLAB_MEM_SPREAD: 0x00100000UL,
	// kmem_cache_create("inode_cache", 394, 0, 0x160000, init_once): kmem_cache#4
	inode_cachep = kmem_cache_create("inode_cache",
					 sizeof(struct inode),
					 0,
					 (SLAB_RECLAIM_ACCOUNT|SLAB_PANIC|
					 SLAB_MEM_SPREAD),
					 init_once);
	// inode_cachep: kmem_cache#4

	/* Hash may have been set up in inode_init_early */
	// hashdist: 0
	if (!hashdist)
		return;
		// return 수행

	inode_hashtable =
		alloc_large_system_hash("Inode-cache",
					sizeof(struct hlist_head),
					ihash_entries,
					14,
					0,
					&i_hash_shift,
					&i_hash_mask,
					0,
					0);

	for (loop = 0; loop < (1U << i_hash_shift); loop++)
		INIT_HLIST_HEAD(&inode_hashtable[loop]);
}
  • inode_init에서 한일:
  • struct inode를 위한 kmem_cache 생성
  • inode_cachep: kmem_cache#4

dcache.c::vfs_caches_init()

  • call
  • start_kerne()->vfs_caches_init()
    • kmem_cache_create(); // names_cache
    • dcache_init()
    • inode_init()
// ARM10C 20151003
// totalram_pages: 총 free된 page 수
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 */

	// NOTE:
	// mempages 값과 nr_free_pages() 의 값을 정확히 알 수 없음
	// 계산된 reserve의 값을 XXX 로 함

	// mempages: 총 free된 page 수, nr_free_pages(): 현재의 free pages 수
	reserve = min((mempages - nr_free_pages()) * 3/2, mempages - 1);
	// reserve: XXX

	// mempages: 총 free된 page 수, reserve: XXX
	mempages -= reserve;
	// mempages: 총 free된 page 수 - XXX

	// PATH_MAX: 4096
	// SLAB_HWCACHE_ALIGN: 0x00002000UL, SLAB_PANIC: 0x00040000UL
	// kmem_cache_create("names_cache", 4096, 0, 0x42000, NULL): kmem_cache#6
	names_cachep = kmem_cache_create("names_cache", PATH_MAX, 0,
			SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
	// names_cachep: kmem_cache#6

	dcache_init();

	// dcache_init에서 한일:
	//
	// struct dentry를 위한 kmem_cache 생성
	// dentry_cache: kmem_cache#5

	inode_init();
	// inode_init에서 한일:
	//
	// struct inode를 위한 kmem_cache 생성
	// inode_cachep: kmem_cache#4

	// mempages: 총 free된 page 수 - XXX
	files_init(mempages);

file_table.c::files_init()

  • call
  • start_kerne()->vfs_caches_init()
    • kmem_cache_create(); // names_cache
    • dcache_init()
    • inode_init()
    • files_init()
  • filp 를 할당받는다.
// ARM10C 20151003
// mempages: 총 free된 page 수 - XXX
void __init files_init(unsigned long mempages)
{ 
	unsigned long n;

	// sizeof(struct file): 160 bytes,
	// SLAB_HWCACHE_ALIGN: 0x00002000UL, SLAB_PANIC: 0x00040000UL,
	// kmem_cache_create("filp", 160, 0, 0x42000, NULL): kmem_cache#3
	filp_cachep = kmem_cache_create("filp", sizeof(struct file), 0,
			SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL);
// ARM10C 20151003
// "filp", sizeof(struct file): 160 bytes, 0, 0x42000, NULL
struct kmem_cache *
kmem_cache_create(const char *name, size_t size, size_t align,
		  unsigned long flags, void (*ctor)(void *))
{
	// name: "filp", size: 160, align: 0, flags: 0x42000, ctor: NULL
	// kmem_cache_create_memcg(NULL, "filp", 160, 0, 0x42000, NULL): kmem_cache#3
	return kmem_cache_create_memcg(NULL, name, size, align, flags, ctor, NULL);
	// return kmem_cache#3
}
// ARM10C 20151003
// mempages: 총 free된 page 수 - XXX
void __init files_init(unsigned long mempages)
{ 
	unsigned long n;

	// sizeof(struct file): 160 bytes,
	// SLAB_HWCACHE_ALIGN: 0x00002000UL, SLAB_PANIC: 0x00040000UL,
	// kmem_cache_create("filp", 160, 0, 0x42000, NULL): kmem_cache#3
	filp_cachep = kmem_cache_create("filp", sizeof(struct file), 0,
			SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL);
	// filp_cachep: kmem_cache#3

	/*
	 * One file with associated inode and dcache is very roughly 1K.
	 * Per default don't use more than 10% of our memory for files. 
	 */ 

	// mempages: 총 free된 page 수 - XXX, PAGE_SIZE: 0x1000
	n = (mempages * (PAGE_SIZE / 1024)) / 10;
	// n: (총 free된 page 수 - XXX) * 4 / 10

	// NOTE:
	// max_t((총 free된 page 수 - XXX) * 4 / 10, 8192) 의 결과값?
	// 계산하여 결과를 구하기 힘듬 (총 free된 page 수 - XXX) * 4 / 10 로 가정하고 분석 진행

	// n: (총 free된 page 수 - XXX) * 4 / 10, NR_FILE: 8192
	// max_t((총 free된 page 수 - XXX) * 4 / 10, 8192): (총 free된 page 수 - XXX) * 4 / 10
	files_stat.max_files = max_t(unsigned long, n, NR_FILE);
	// files_stat.max_files: (총 free된 page 수 - XXX) * 4 / 10

	files_defer_init();

file.c::files_defer_init()

  • call
  • start_kerne()->vfs_caches_init()
    • kmem_cache_create(); // names_cache
    • dcache_init()
    • inode_init()
    • files_init()
      • files_defer_init()
// ARM10C 20151003
void __init files_defer_init(void)
{
	// sysctl_nr_open_max: 0x100000, INT_MAX: 0x7FFFFFFF
	// min(0x7FFFFFFF, 0x3FFFFFFF): 0x3FFFFFFF, -BITS_PER_LONG: 0xFFFFFFE0
	sysctl_nr_open_max = min((size_t)INT_MAX, ~(size_t)0/sizeof(void *)) &
			     -BITS_PER_LONG;
	// sysctl_nr_open_max: 0x3FFFFFE0
}
  • files_defer_init에서 한일:
  • sysctl_nr_open_max: 0x3FFFFFE0

dcache.c::vfs_caches_init()

  • call
  • start_kerne()->vfs_caches_init()
    • kmem_cache_create(); // names_cache
    • dcache_init()
    • inode_init()
// ARM10C 20151003
// totalram_pages: 총 free된 page 수
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 */

	// NOTE:
	// mempages 값과 nr_free_pages() 의 값을 정확히 알 수 없음
	// 계산된 reserve의 값을 XXX 로 함

	// mempages: 총 free된 page 수, nr_free_pages(): 현재의 free pages 수
	reserve = min((mempages - nr_free_pages()) * 3/2, mempages - 1);
	// reserve: XXX

	// mempages: 총 free된 page 수, reserve: XXX
	mempages -= reserve;
	// mempages: 총 free된 page 수 - XXX

	// PATH_MAX: 4096
	// SLAB_HWCACHE_ALIGN: 0x00002000UL, SLAB_PANIC: 0x00040000UL
	// kmem_cache_create("names_cache", 4096, 0, 0x42000, NULL): kmem_cache#6
	names_cachep = kmem_cache_create("names_cache", PATH_MAX, 0,
			SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
	// names_cachep: kmem_cache#6

	dcache_init();

	// dcache_init에서 한일:
	//
	// struct dentry를 위한 kmem_cache 생성
	// dentry_cache: kmem_cache#5

	inode_init();
	// inode_init에서 한일:
	//
	// struct inode를 위한 kmem_cache 생성
	// inode_cachep: kmem_cache#4

	// mempages: 총 free된 page 수 - XXX
	files_init(mempages);

log

  • 1st log
e356946..8be65be  master     -> origin/master
Updating e356946..8be65be
Fast-forward
arch/arm/include/asm/atomic.h               |  3 +-
arch/arm/include/asm/mmu.h                  |  6 ++-
arch/arm/include/asm/pgtable-2level-types.h |  1 +
arch/arm/include/asm/processor.h            |  5 +-
fs/buffer.c                                 | 19 +++++++
fs/dcache.c                                 | 20 +++++++
fs/fat/inode.c                              |  1 +
fs/file.c                                   |  2 +-
fs/file_table.c                             |  7 +++
fs/inode.c                                  |  5 ++
include/asm-generic/atomic-long.h           |  2 +
include/asm-generic/bitsperlong.h           |  1 +
include/asm-generic/cputime_jiffies.h       |  1 +
include/linux/auxvec.h                      |  2 +
include/linux/backing-dev.h                 |  2 +
include/linux/binfmts.h                     |  1 +
include/linux/bio.h                         |  2 +
include/linux/blkdev.h                      |  2 +-
include/linux/buffer_head.h                 |  5 +-
include/linux/cgroup.h                      |  1 +
include/linux/completion.h                  |  2 +
include/linux/cpu.h                         | 12 ++++-
include/linux/cpumask.h                     |  2 +
include/linux/cred.h                        |  1 +
include/linux/dcache.h                      | 15 +++++-
include/linux/fdtable.h                     |  8 +++
include/linux/fs.h                          | 30 ++++++++---
include/linux/fs_struct.h                   |  2 +
include/linux/gfp.h                         | 19 +++++++
include/linux/iocontext.h                   |  1 +
include/linux/kconfig.h                     |  1 +
include/linux/ktime.h                       |  3 ++
include/linux/list_bl.h                     |  2 +
include/linux/llist.h                       |  1 +
include/linux/lockref.h                     |  7 +++
include/linux/mm_types.h                    | 49 +++++++++++++----
include/linux/mutex.h                       |  3 ++
include/linux/nsproxy.h                     |  2 +
include/linux/path.h                        |  2 +
include/linux/pid.h                         |  6 +++
include/linux/pipe_fs_i.h                   |  1 +
include/linux/plist.h                       |  4 ++
include/linux/posix_acl.h                   |  1 +
include/linux/radix-tree.h                  |  1 +
include/linux/rbtree.h                      |  1 +
include/linux/rwlock_types.h                |  8 +--
include/linux/sched.h                       | 22 +++++++-
include/linux/seccomp.h                     |  3 +-
include/linux/sem.h                         |  4 +-
include/linux/seqlock.h                     |  1 +
include/linux/signal.h                      |  2 +
include/linux/slab.h                        | 15 ++++++
include/linux/swap.h                        |  1 +
include/linux/task_io_accounting.h          |  5 +-
include/linux/tty.h                         |  1 +
include/linux/types.h                       | 17 +++++-
include/linux/uidgid.h                      |  2 +
include/linux/uprobes.h                     |  3 +-
include/uapi/asm-generic/posix_types.h      |  4 ++
include/uapi/asm-generic/resource.h         |  2 +
include/uapi/asm-generic/siginfo.h          |  1 +
include/uapi/linux/futex.h                  |  1 +
include/uapi/linux/limits.h                 |  2 +
include/uapi/linux/resource.h               |  2 +
include/uapi/linux/time.h                   |  2 +
init/main.c                                 |  5 ++
ipc/sem.c                                   |  1 +
kernel/audit.h                              |  1 +
kernel/bounds.c                             |  3 +-
kernel/cpu.c                                | 16 ++++++
kernel/fork.c                               | 41 ++++++++++++--
kernel/futex.c                              |  1 +
kernel/locking/rtmutex_common.h             |  1 +
kernel/notifier.c                           | 11 ++++
kernel/nsproxy.c                            |  7 +++
kernel/sched/sched.h                        |  3 ++
lib/percpu_counter.c                        |  1 +
mm/page_alloc.c                             | 10 ++++
mm/slab_common.c                            | 83 +++++++++++++++++++++++++++--
79 files changed, 498 insertions(+), 48 deletions(-)