Skip to content

Latest commit

 

History

History
622 lines (504 loc) · 19.4 KB

a10c_120.md

File metadata and controls

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

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

120 주차 진도

  • 119주차 진도를 복습하였습니다.

  • 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()

  • 지난주는 자기 충전의 시간을 가지고 다시 커널 소스 분석을 시작합니다.

  • vfs_caches_init()

  • start_kernel 1 ~/kernel/iamroot/linux-stable/init/main.c
    • vfs_caches_init 925 ~/kernel/iamroot/linux-stable/init/main.c
    • files_init 3485 ~/kernel/iamroot/linux-stable/fs/dcache.c

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 정보로 사용

...

	// 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_kernel()->vfs_caches_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_kernel()->vfs_caches_init()
  • files_init()
// 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();

	// files_defer_init에서 한일:
	// sysctl_nr_open_max: 0x3FFFFFE0

// 2015/10/03 종료
// 2015/10/24 시작

	percpu_counter_init(&nr_files, 0);

percpu_counter.h::percpu_counter_init()

  • call: start_kernel()->vfs_caches_init()
  • dcache_init()
  • inode_init()
  • files_init()
// ARM10C 20151024
// &nr_files, 0
#define percpu_counter_init(fbc, value)					\
	({								\
		static struct lock_class_key __key;			\
									\
		__percpu_counter_init(fbc, value, &__key);		\
	})

percpu_counter.c::__percpu_counter_init()

  • call: start_kernel()->vfs_caches_init()
  • dcache_init()
  • inode_init()
  • files_init()
  • percpu_counter_init()
    • __percpu_counter_init()
// ARM10C 20151024
// &nr_files, 0, &__key
int __percpu_counter_init(struct percpu_counter *fbc, s64 amount,
			  struct lock_class_key *key)
{
	// &fbc->lock: &(&vm_committed_as)->lock
	raw_spin_lock_init(&fbc->lock);

	// raw_spin_lock_init에서 한일:
	// (&(&(&(&vm_committed_as)->lock)->wait_lock)->rlock)->raw_lock: { { 0 } }
	// (&(&(&(&vm_committed_as)->lock)->wait_lock)->rlock)->magic: 0xdead4ead
	// (&(&(&(&vm_committed_as)->lock)->wait_lock)->rlock)->owner: 0xffffffff
	// (&(&(&(&vm_committed_as)->lock)->wait_lock)->rlock)->owner_cpu: 0xffffffff

	// &fbc->lock: &(&vm_committed_as)->lock, key: &__key
	lockdep_set_class(&fbc->lock, key); // null function

	// fbc->count: (&vm_committed_as)->count, amount: 0
	fbc->count = amount;
	// fbc->count: (&vm_committed_as)->count: 0

	// fbc->counters: (&vm_committed_as)->counters,
	// alloc_percpu(s32): kmem_cache#26-o0 에서 할당된 4 bytes 메모리 주소
	fbc->counters = alloc_percpu(s32);
	// fbc->counters: (&vm_committed_as)->counters: kmem_cache#26-o0 에서 할당된 4 bytes 메모리 주소

	// fbc->counters: (&vm_committed_as)->counters: kmem_cache#26-o0 에서 할당된 4 bytes 메모리 주소
	if (!fbc->counters)
		return -ENOMEM;

	// fbc: &vm_committed_as
	debug_percpu_counter_activate(fbc); // null function

#ifdef CONFIG_HOTPLUG_CPU // CONFIG_HOTPLUG_CPU=y
	// &fbc->list: &(&vm_committed_as)->list
	INIT_LIST_HEAD(&fbc->list);

	// INIT_LIST_HEAD에서 한일:
	// (&(&vm_committed_as)->list)->next: &(&vm_committed_as)->list
	// (&(&vm_committed_as)->list)->prev: &(&vm_committed_as)->list

	spin_lock(&percpu_counters_lock);

	// spin_lock에서 한일:
	// &percpu_counters_lock을 사용한 spin lock 수행

	// &fbc->list: &(&vm_committed_as)->list
	list_add(&fbc->list, &percpu_counters);

	// list_add에서 한일:
	// list head 인 &percpu_counters에 &(&vm_committed_as)->list를 연결함

	spin_unlock(&percpu_counters_lock);

	// spin_lock에서 한일:
	// &percpu_counters_lock을 사용한 spin unlock 수행
#endif
	return 0;
	// return 0
}
EXPORT_SYMBOL(__percpu_counter_init);
  • percpu_counter_init에서 한일:
  • (&(&(&(&nr_files)->lock)->wait_lock)->rlock)->raw_lock: { { 0 } }
  • (&(&(&(&nr_files)->lock)->wait_lock)->rlock)->magic: 0xdead4ead
  • (&(&(&(&nr_files)->lock)->wait_lock)->rlock)->owner: 0xffffffff
  • (&(&(&(&nr_files)->lock)->wait_lock)->rlock)->owner_cpu: 0xffffffff
  • (&(&nr_files)->list)->next: &(&nr_files)->list
  • (&(&nr_files)->list)->prev: &(&nr_files)->list
  • (&nr_files)->count: 0
  • (&nr_files)->counters: kmem_cache#26-o0 에서 할당된 4 bytes 메모리 주소
  • list head 인 &percpu_counters에 &(&nr_files)->list를 연결함

dcache.c::vfs_caches_init()

  • return: start_kernel()->vfs_caches_init()->files_init()

  • files_init에서 한일:

  • filp_cachep: kmem_cache#3
  • files_stat.max_files: (총 free된 page 수 - XXX) * 4 / 10
  • sysctl_nr_open_max: 0x3FFFFFE0
  • (&(&(&(&nr_files)->lock)->wait_lock)->rlock)->raw_lock: { { 0 } }
  • (&(&(&(&nr_files)->lock)->wait_lock)->rlock)->magic: 0xdead4ead
  • (&(&(&(&nr_files)->lock)->wait_lock)->rlock)->owner: 0xffffffff
  • (&(&(&(&nr_files)->lock)->wait_lock)->rlock)->owner_cpu: 0xffffffff
  • (&(&nr_files)->list)->next: &(&nr_files)->list
  • (&(&nr_files)->list)->prev: &(&nr_files)->list
  • (&nr_files)->count: 0
  • (&nr_files)->counters: kmem_cache#26-o0 에서 할당된 4 bytes 메모리 주소
  • list head 인 &percpu_counters에 &(&nr_files)->list를 연결함
// 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);

	mnt_init();

namespace.c::mnt_init()

  • mnt_cahce를 할당받는다.
// ARM10C 20151024
void __init mnt_init(void)
{
	unsigned u;
	int err;

	// sizeof(struct mount): 152 bytes, SLAB_HWCACHE_ALIGN: 0x00002000UL, SLAB_PANIC: 0x00040000UL
	// kmem_cache_create("mnt_cache", 152, 0, 0x42000, NULL): kmem_cache#2
	mnt_cache = kmem_cache_create("mnt_cache", sizeof(struct mount),
			0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL);
// ARM10C 20151024
// "mnt_cache", sizeof(struct mount): 152 bytes, 0, 0x00042000, NULL
struct kmem_cache *
kmem_cache_create(const char *name, size_t size, size_t align,
		  unsigned long flags, void (*ctor)(void *))
{
	// name: "mnt_cache", size: 152, align: 0, flags: 0x42000, ctor: NULL
	// kmem_cache_create_memcg(NULL, "mnt_cache", 152, 0, 0x42000, NULL): kmem_cache#2
	return kmem_cache_create_memcg(NULL, name, size, align, flags, ctor, NULL);
	// return kmem_cache#2
}
EXPORT_SYMBOL(kmem_cache_create);
  • alloc_large_system_hash
// ARM10C 20151024
void __init mnt_init(void)
{
	unsigned u;
	int err;

	// sizeof(struct mount): 152 bytes, SLAB_HWCACHE_ALIGN: 0x00002000UL, SLAB_PANIC: 0x00040000UL
	// kmem_cache_create("mnt_cache", 152, 0, 0x42000, NULL): kmem_cache#2
	mnt_cache = kmem_cache_create("mnt_cache", sizeof(struct mount),
			0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL);
	// mnt_cache: kmem_cache#2

	// sizeof(struct hlist_head): 4 bytes, mhash_entries: 0
	// alloc_large_system_hash("Mount-cache", 4, 0, 19, 0, &m_hash_shift, &m_hash_mask, 0, 0): 16kB만큼 할당받은 메모리 주소
	mount_hashtable = alloc_large_system_hash("Mount-cache",
				sizeof(struct hlist_head),
				mhash_entries, 19,
				0,
				&m_hash_shift, &m_hash_mask, 0, 0);

page_alloc.c::alloc_large_system_hash()

// ARM10C 20151024
// [mCA] tablename: "Mount-cache", bucketsize: 4,
// numentries: 0, scale: 19,
// flags: 0,
// *_hash_shift : &m_hash_shift, *_hash_mask : &m_hash_mask,
// low_limit: 0, high_limit: 0
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 low_limit,
				     unsigned long high_limit)
{
	// [mCA] high_limit: 0
	unsigned long long max = high_limit;
	// [mCA] max : 0

	unsigned long log2qty, size;
	void *table = NULL;
	// [mCA] table: NULL

	/* allow the kernel cmdline to have a say */
	// [mCA] numentries: 0
	if (!numentries) {
		// [mCA] numentries : 0 이므로 if문 실행

		/* round applicable memory size up to nearest megabyte */
		// [mCA] static unsigned long __meminitdata nr_kernel_pages
		// [mCA] nr_kernel_pages : 0x2EFD6
		numentries = nr_kernel_pages;
		// [mCA] numentries : 0x2EFD6

		/* It isn't necessary when PAGE_SIZE >= 1MB */
		// [mCA] PAGE_SHIFT: 12
		if (PAGE_SHIFT < 20)
			// [mCA] numentries : 0x2EFD6, PAGE_SIZE: 0x1000, (1UL << 20) / 0x1000): 0xFF
			numentries = round_up(numentries, (1<<20)/PAGE_SIZE);
			// [mCA] numentries : 0x2F000

		/* limit to 1 bucket per 2^scale bytes of low memory */
		// [mCA] scale : (19 > 12), PAGE_SHIFT: 12
		if (scale > PAGE_SHIFT)
			// [mCA] numentries: 0x2F000, scale: 19, PAGE_SHIFT: 12
			numentries >>= (scale - PAGE_SHIFT);
			// [mCA] numentries >>= (scale : 19 - PAGE_SHIFT: 12)
			// [mCA] numentries : 0x5E0 : 0x2F000 >> 7:
		else
			numentries <<= (PAGE_SHIFT - scale);

		/* Make sure we've got at least a 0-order allocation.. */
		// [mCA] unlikely (0x00000000) : flags : 0x00000000 & HASH_SMALL 0x00000002
		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))
		// [mCA] unlikely(0x2F000 : (0x5E0 * 4) < 0x1000)
			numentries = PAGE_SIZE / bucketsize;
	}

	// [mCA] numentries : 0x5E0 : 1504
	numentries = roundup_pow_of_two(numentries);
	// [mCA] numentries : 1024
	
	/* limit allocation size to 1/16 total memory by default */
	// [mCA] max : 0
	if (max == 0) {
		// [mCA] nr_all_pages: 0x7EA00, PAGE_SHIFT: 12
		max = ((unsigned long long)nr_all_pages << PAGE_SHIFT) >> 4;
		// [mCA] max = (nr_all_pages : 0x7EA0000 : 0x7EA00000 >> 4 : 0x7EA00  << 12) >> 4

		// [mCA] max : 0x7EA0000, bucketsize : 4
		do_div(max, bucketsize);
		// [mCA] max : 0x1FA8000
	}

	// [mCA] max : 0x1FA8000 : min(0x1FA8000, 0x80000000ULL)
	max = min(max, 0x80000000ULL);
	// [mCA] max : 0x1FA8000

	// [mCA] numentries :   1024 < 0, low_limit: 0
	if (numentries < low_limit)
		numentries = low_limit;

	// [mCA] numentries :   1024 > 33193984 : 0x1FA8000
	if (numentries > max)
		numentries = max;

	// [mCA] numentries :  1024
	log2qty = ilog2(numentries);
	// [mCA] log2qty : 12 : ilog2(1024)
	
	do {
		// [mCA] bucketsize: 4, log2qty : 12
		size = bucketsize << log2qty;
		// [mCA] size = 0x4000 (16kB) : 4 << 12

		// [mCA] 0x00000000 : flags : 0x00000001 & HASH_EARLY : 0x00000001, hashdist: 0
		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
			 */
			// [mCA] size: 0x4000 (16kB), get_order(0x4000): 2, MAX_ORDER: 11
			if (get_order(size) < MAX_ORDER) {
				// [mCA] size: 0x4000 (16kB), GFP_ATOMIC: 0x20u
				// [mCA] alloc_pages_exact(0x4000, 0x20): migratetype이 MIGRATE_UNMOVABLE인 order 2의 page의 가상주소
				table = alloc_pages_exact(size, GFP_ATOMIC);
				// [mCA] table: migratetype이 MIGRATE_UNMOVABLE인 order 2의 page의 가상주소

				// [mCA] alloc_pages_exact 에서 한일:
				// migratetype이 MIGRATE_UNMOVABLE인 order 2의 page의 가상메모리 공간을 할당받고
				// migratetype이 MIGRATE_UNMOVABLE인 order 2의 page들의 _count를 1로 set (order 2이면 page 4개)
				// 각각의 page의 _count 값을 바꾸어 page를 split 함

				// [mCA] table: migratetype이 MIGRATE_UNMOVABLE인 order 2의 page의 가상주소, size: 0x4000 (16kB), GFP_ATOMIC: 0x20u
				kmemleak_alloc(table, size, 1, GFP_ATOMIC); // null function
			}
		}
	} while (!table && size > PAGE_SIZE && --log2qty);

	// [mCA] table : 16kB만큼 할당받은 메모리 주소
	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);
	// [mCA] Mount-cache hash table entries: 4096 (order: 2, 4096 bytes)

	// [mCA] _hash_shift : &m_hash_shift
	if (_hash_shift)
		// [mCA] log2qty : 12
		*_hash_shift = log2qty;
		// [mCA] *_hash_shift: m_hash_shift: 12

	// [mCA] _hash_mask : m_hash_mask
	if (_hash_mask)
		// [mCA] log2qty : 12, _hash_mask : m_hash_mask
		*_hash_mask = (1 << log2qty) - 1;
		// [mCA] *_hash_mask : (4095) 0xFFF : (1 << 12 ) - 1

	// [mCA] table : 16kB만큼 할당받은 메모리 주소
	return table;
	// [mCA] return 16kB만큼 할당받은 메모리 주소
}
// ARM10C 20151024
void __init mnt_init(void)
{
	unsigned u;
	int err;

	// sizeof(struct mount): 152 bytes, SLAB_HWCACHE_ALIGN: 0x00002000UL, SLAB_PANIC: 0x00040000UL
	// kmem_cache_create("mnt_cache", 152, 0, 0x42000, NULL): kmem_cache#2
	mnt_cache = kmem_cache_create("mnt_cache", sizeof(struct mount),
			0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL);
	// mnt_cache: kmem_cache#2

	// sizeof(struct hlist_head): 4 bytes, mhash_entries: 0
	// alloc_large_system_hash("Mount-cache", 4, 0, 19, 0, &m_hash_shift, &m_hash_mask, 0, 0): 16kB만큼 할당받은 메모리 주소
	mount_hashtable = alloc_large_system_hash("Mount-cache",
				sizeof(struct hlist_head),
				mhash_entries, 19,
				0,
				&m_hash_shift, &m_hash_mask, 0, 0);
	// mount_hashtable: 16kB만큼 할당받은 메모리 주소

log

8be65be..4cba12e  master     -> origin/master
Updating 8be65be..4cba12e
Fast-forward
arch/arm/include/asm/bitops.h      |   2 +
arch/arm/include/asm/memory.h      |   3 +
arch/arm/include/asm/page.h        |   2 +
fs/dcache.c                        |  17 +++++
fs/file_table.c                    |  13 ++++
fs/mount.h                         |   7 +-
fs/namespace.c                     |  15 ++++
include/asm-generic/getorder.h     |  11 +++
include/asm-generic/memory_model.h |   1 +
include/linux/gfp.h                |   1 +
include/linux/kmemleak.h           |   1 +
include/linux/log2.h               |   2 +
include/linux/mm.h                 |  14 ++++
include/linux/mmzone.h             |   1 +
include/linux/mount.h              |   2 +
include/linux/page-flags.h         |   4 +
include/linux/percpu_counter.h     |   5 ++
include/linux/slab.h               |   2 +
include/linux/slub_def.h           |   1 +
include/linux/types.h              |   6 +-
init/main.c                        |   4 +
lib/percpu_counter.c               |   2 +
mm/internal.h                      |   2 +
mm/page_alloc.c                    | 202 ++++++++++++++++++++++++++++++++++++++++++--------
mm/slab_common.c                   |   7 ++
25 files changed, 294 insertions(+), 33 deletions(-)
  • 2nd log
d153cd2..a463952  master     -> origin/master
Updating d153cd2..a463952
Fast-forward
fs/namespace.c       |   8 ++-
include/linux/log2.h |   2 +
mm/page_alloc.c      | 410 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------------------------
3 files changed, 245 insertions(+), 175 deletions(-)