138주차 (2016.04.02) vfs_caches_init()


#1
KernelStudy : 138 주차
일시 : 2016.04.02 (138주차 스터디 진행)
모임명 : KernelStudy_ARM
장소 : 토즈 서현점
장소지원 : 공개 소프트웨어 개발자 커뮤니티 지원 프로그램
참여인원 : 3명

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

138 주차 진도

  • ᇂ138차 시작 위치
  • start_kernel 1 ~/init/main.c
  • vfs_caches_init 925 ~/init/main.c
  • mnt_init 3809 ~/fs/dcache.c
  • init_mount_tree 5046 ~/fs/namespace.c
  • get_fs_type 3994 ~/fs/namespace.c
  • __get_fs_type 402 ~/fs/filesystems.c
  • read_lock 379 ~/fs/filesystems.c
  • _raw_read_lock 74 ~/include/linux/rwlock.h
  • __raw_read_lock 231 ~/kernel/locking/spinlock.c
  • do_raw_read_lock 152 ~/include/linux/rwlock_api_smp.h
  • arch_read_lock 254 ~/kernel/locking/spinlock_debug.c
  • 137주차 함수 호출 구조
  • 주석이 잘못 된부분을 발견해서 sysfs_init()를 수정.
  • call: start_kernel()
  • vfs_caches_init()
  • kmem_cache_create(): names_cache
  • dcache_init()
  • inode_init()
  • files_init()
  • mnt_init()
  • call: mnt_init()

    • kmem_cache_create()
    • alloc_large_system_hash() : mnt_cache
    • alloc_large_system_hash() : Mount-cache
    • alloc_large_system_hash() : Mountpoint-cache
    • INIT_HLIST_HEAD() : &mount_hashtable[u]
    • INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
    • sysfs_init()
    • kobject_create_and_add() : fs
    • init_rootfs()
    • init_mount_tree()
  • call: init_mount_tree()

  • get_fs_type 3994 ~/fs/namespace.c
  • call: __get_fs_type() 402 ~/fs/filesystems.c
  • read_lock 379 ~/fs/filesystems.c
  • call: _raw_read_lock() 74 ~/include/linux/rwlock.h

  • call: __raw_read_lock() 231 ~/kernel/locking/spinlock.c

  • call: do_raw_read_lock 152 ~/include/linux/rwlock_api_smp.h

  • call: arch_read_lock 254 ~/kernel/locking/spinlock_debug.c

    • prefetchw()

main.c::start_kernel()

  • call: start_kernel()->vfs_caches_init()
asmlinkage void __init start_kernel(void)
{
	char * command_line;
	extern const struct kernel_param __start___param[], __stop___param[];
	// ATAG,DTB 정보로 사용

...

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

	inode_init();

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

	mnt_init();

namespace.c::mnt_init()

  • call: start_kernel()

    • vfs_caches_init()
  • call: vfs_caches_init()

    • kmem_cache_create(): names_cache
    • dcache_init()
    • inode_init()
    • files_init()
    • mnt_init()
// 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만큼 할당받은 메모리 주소

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

	// mount_hashtable: 16kB만큼 할당받은 메모리 주소, mountpoint_hashtable: 16kB만큼 할당받은 메모리 주소
	if (!mount_hashtable || !mountpoint_hashtable)
		panic("Failed to allocate mount hash table\n");

	// m_hash_mask: 0xFFF
	for (u = 0; u <= m_hash_mask; u++)
		// u: 0
		INIT_HLIST_HEAD(&mount_hashtable[u]);

		// INIT_HLIST_HEAD 에서 한일:
		// ((&mount_hashtable[0])->first = NULL)

		// u: 1...4095 까지 loop 수행

	// mp_hash_mask: 0xFFF
	for (u = 0; u <= mp_hash_mask; u++)
		// u: 0
		INIT_HLIST_HEAD(&mountpoint_hashtable[u]);

		// INIT_HLIST_HEAD 에서 한일:
		// ((&mountpoint_hashtable[0])->first = NULL)

		// u: 1...4095 까지 loop 수행

	// sysfs_init(): 0
	err = sysfs_init();
	// err: 0

	// err: 0
	if (err)
		printk(KERN_WARNING "%s: sysfs_init error: %d\n",
			__func__, err);

	// kobject_create_and_add("fs", NULL): kmem_cache#30-oX (struct kobject)
	fs_kobj = kobject_create_and_add("fs", NULL);
	// fs_kobj: kmem_cache#30-oX (struct kobject)

	// fs_kobj: kmem_cache#30-oX (struct kobject)
	if (!fs_kobj)
		printk(KERN_WARNING "%s: kobj create error\n", __func__);

	init_rootfs();

    init_mount_tree();

namespace.c::init_mount_tree()

  • call: start_kernel()
  • vfs_caches_init()
  • kmem_cache_create(): names_cache
  • dcache_init()
  • inode_init()
  • files_init()
  • mnt_init()
  • call: mnt_init()

    • kmem_cache_create()
    • alloc_large_system_hash() : mnt_cache
    • alloc_large_system_hash() : Mount-cache
    • alloc_large_system_hash() : Mountpoint-cache
    • INIT_HLIST_HEAD() : &mount_hashtable[u]
    • INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
    • sysfs_init()
    • kobject_create_and_add() : fs
    • init_rootfs()
    • init_mount_tree()
  • call: init_mount_tree()

  • get_fs_type 3994 ~/fs/namespace.c
// ARM10C 20160326
static void __init init_mount_tree(void)
{
	struct vfsmount *mnt;
	struct mnt_namespace *ns;
	struct path root;
	struct file_system_type *type;

	type = get_fs_type("rootfs");

filesystems.cc::get_fs_type()

  • call: start_kernel()
  • vfs_caches_init()
  • kmem_cache_create(): names_cache
  • dcache_init()
  • inode_init()
  • files_init()
  • mnt_init()
  • call: mnt_init()

    • kmem_cache_create()
    • alloc_large_system_hash() : mnt_cache
    • alloc_large_system_hash() : Mount-cache
    • alloc_large_system_hash() : Mountpoint-cache
    • INIT_HLIST_HEAD() : &mount_hashtable[u]
    • INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
    • sysfs_init()
    • kobject_create_and_add() : fs
    • init_rootfs()
    • init_mount_tree()
  • call: init_mount_tree()

  • get_fs_type 3994 ~/fs/namespace.c
  • call: __get_fs_type() 402 ~/fs/filesystems.c
// ARM10C 20160326
// "rootfs"
struct file_system_type *get_fs_type(const char *name)
{
	struct file_system_type *fs;

	// name: "rootfs", strchr("rootfs". '.'): NULL
	const char *dot = strchr(name, '.');
	// dot: NULL

	// dot: NULL, name: "rootfs", strlen("rootfs"): 6
	int len = dot ? dot - name : strlen(name);
	// len: 6

	// name: "rootfs", len: 6
	fs = __get_fs_type(name, len);

filesystems.c::__get_fs_type()

  • call: start_kernel()
  • vfs_caches_init()
  • kmem_cache_create(): names_cache
  • dcache_init()
  • inode_init()
  • files_init()
  • mnt_init()
  • call: mnt_init()

    • kmem_cache_create()
    • alloc_large_system_hash() : mnt_cache
    • alloc_large_system_hash() : Mount-cache
    • alloc_large_system_hash() : Mountpoint-cache
    • INIT_HLIST_HEAD() : &mount_hashtable[u]
    • INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
    • sysfs_init()
    • kobject_create_and_add() : fs
    • init_rootfs()
    • init_mount_tree()
  • call: init_mount_tree()

  • get_fs_type 3994 ~/fs/namespace.c
  • call: __get_fs_type() 402 ~/fs/filesystems.c
  • __get_fs_type()
// ARM10C 20160326
// name: "rootfs", len: 6
static struct file_system_type *__get_fs_type(const char *name, int len)
{
	struct file_system_type *fs;

	read_lock(&file_systems_lock);

rwlock.h::_read_lock()

  • call: start_kernel()
  • vfs_caches_init()
  • kmem_cache_create(): names_cache
  • dcache_init()
  • inode_init()
  • files_init()
  • mnt_init()
  • call: mnt_init()

    • kmem_cache_create()
    • alloc_large_system_hash() : mnt_cache
    • alloc_large_system_hash() : Mount-cache
    • alloc_large_system_hash() : Mountpoint-cache
    • INIT_HLIST_HEAD() : &mount_hashtable[u]
    • INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
    • sysfs_init()
    • kobject_create_and_add() : fs
    • init_rootfs()
    • init_mount_tree()
  • call: init_mount_tree()

  • get_fs_type 3994 ~/fs/namespace.c
  • call: __get_fs_type() 402 ~/fs/filesystems.c
  • __get_fs_type()
  • call: __get_fs_type()
// ARM10C 20160326
// &file_systems_lock
#define read_lock(lock)		_raw_read_lock(lock)

spinlock.c::_raw_read_lock()

  • call: start_kernel()
  • vfs_caches_init()
  • kmem_cache_create(): names_cache
  • dcache_init()
  • inode_init()
  • files_init()
  • mnt_init()
  • call: mnt_init()

    • kmem_cache_create()
    • alloc_large_system_hash() : mnt_cache
    • alloc_large_system_hash() : Mount-cache
    • alloc_large_system_hash() : Mountpoint-cache
    • INIT_HLIST_HEAD() : &mount_hashtable[u]
    • INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
    • sysfs_init()
    • kobject_create_and_add() : fs
    • init_rootfs()
    • init_mount_tree()
  • call: init_mount_tree()

  • get_fs_type 3994 ~/fs/namespace.c
  • call: __get_fs_type() 402 ~/fs/filesystems.c
  • __get_fs_type()
  • call: __get_fs_type()

    • read_lock(): _raw_read_lock()
  • call: _raw_read_lock()

// ARM10C 20160326
// &file_systems_lock
void __lockfunc _raw_read_lock(rwlock_t *lock)
{
	// lock: &file_systems_lock
	__raw_read_lock(lock);
}
EXPORT_SYMBOL(_raw_read_lock);

rwlock_api_smp.h::__raw_read_lock()

  • call: start_kernel()
  • vfs_caches_init()
  • kmem_cache_create(): names_cache
  • dcache_init()
  • inode_init()
  • files_init()
  • mnt_init()
  • call: mnt_init()

    • kmem_cache_create()
    • alloc_large_system_hash() : mnt_cache
    • alloc_large_system_hash() : Mount-cache
    • alloc_large_system_hash() : Mountpoint-cache
    • INIT_HLIST_HEAD() : &mount_hashtable[u]
    • INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
    • sysfs_init()
    • kobject_create_and_add() : fs
    • init_rootfs()
    • init_mount_tree()
  • call: init_mount_tree()

  • get_fs_type 3994 ~/fs/namespace.c
  • call: __get_fs_type() 402 ~/fs/filesystems.c
  • __get_fs_type()
  • call: __get_fs_type()

    • read_lock(): _raw_read_lock()
  • call: _raw_read_lock()

    • __raw_read_lock();
  • call: __raw_read_lock()

// ARM10C 20160326
// lock: &file_systems_lock
static inline void __raw_read_lock(rwlock_t *lock)
{
	preempt_disable();
	rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); // null function
	LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock);
}

rwlock.h::do_raw_read_lock()

  • call: start_kernel()
  • vfs_caches_init()
  • kmem_cache_create(): names_cache
  • dcache_init()
  • inode_init()
  • files_init()
  • mnt_init()
  • call: mnt_init()

    • kmem_cache_create()
    • alloc_large_system_hash() : mnt_cache
    • alloc_large_system_hash() : Mount-cache
    • alloc_large_system_hash() : Mountpoint-cache
    • INIT_HLIST_HEAD() : &mount_hashtable[u]
    • INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
    • sysfs_init()
    • kobject_create_and_add() : fs
    • init_rootfs()
    • init_mount_tree()
  • call: init_mount_tree()

  • get_fs_type 3994 ~/fs/namespace.c
  • call: __get_fs_type() 402 ~/fs/filesystems.c
  • __get_fs_type()
  • call: __get_fs_type()

    • read_lock(): _raw_read_lock()
  • call: _raw_read_lock()

    • __raw_read_lock();
  • call: __raw_read_lock()

    • preempt_disable()
    • rwlock_acquire_read()
    • LOCK_CONTENDED(): do_raw_read_lock()
// ARM10C 20160326
 extern void do_raw_read_lock(rwlock_t *lock) __acquires(lock);

spinlock_debug.c

  • call: start_kernel()
  • vfs_caches_init()
  • kmem_cache_create(): names_cache
  • dcache_init()
  • inode_init()
  • files_init()
  • mnt_init()
  • call: mnt_init()

    • kmem_cache_create()
    • alloc_large_system_hash() : mnt_cache
    • alloc_large_system_hash() : Mount-cache
    • alloc_large_system_hash() : Mountpoint-cache
    • INIT_HLIST_HEAD() : &mount_hashtable[u]
    • INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
    • sysfs_init()
    • kobject_create_and_add() : fs
    • init_rootfs()
    • init_mount_tree()
  • call: init_mount_tree()

  • get_fs_type 3994 ~/fs/namespace.c
  • call: __get_fs_type() 402 ~/fs/filesystems.c
  • __get_fs_type()
  • call: __get_fs_type()

    • read_lock(): _raw_read_lock()
  • call: _raw_read_lock()

    • __raw_read_lock();
  • call: __raw_read_lock()

    • preempt_disable()
    • rwlock_acquire_read()
    • LOCK_CONTENDED(): do_raw_read_lock()
// ARM10C 20160326
// &file_systems_lock
void do_raw_read_lock(rwlock_t *lock)
{
	// lock->magic: (&file_systems_lock)->magic: 0xdeaf1eed, RWLOCK_MAGIC: 0xdeaf1eed, lock: &file_systems_lock
	RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic");

	// &lock->raw_lock: &(&file_systems_lock)->raw_lock
	arch_read_lock(&lock->raw_lock);
}

spinlock_debug.c::do_raw_read_lock()

  • call: start_kernel()
  • vfs_caches_init()
  • kmem_cache_create(): names_cache
  • dcache_init()
  • inode_init()
  • files_init()
  • mnt_init()
  • call: mnt_init()

    • kmem_cache_create()
    • alloc_large_system_hash() : mnt_cache
    • alloc_large_system_hash() : Mount-cache
    • alloc_large_system_hash() : Mountpoint-cache
    • INIT_HLIST_HEAD() : &mount_hashtable[u]
    • INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
    • sysfs_init()
    • kobject_create_and_add() : fs
    • init_rootfs()
    • init_mount_tree()
  • call: init_mount_tree()

  • get_fs_type 3994 ~/fs/namespace.c
  • call: __get_fs_type() 402 ~/fs/filesystems.c
  • __get_fs_type()
  • call: __get_fs_type()

    • read_lock(): _raw_read_lock()
  • call: _raw_read_lock()

    • __raw_read_lock();
  • call: __raw_read_lock()

    • preempt_disable()
    • rwlock_acquire_read()
    • LOCK_CONTENDED(): do_raw_read_lock()
  • call: do_raw_read_lock()

// ARM10C 20160326
// &file_systems_lock
void do_raw_read_lock(rwlock_t *lock)
{
	// lock->magic: (&file_systems_lock)->magic: 0xdeaf1eed, RWLOCK_MAGIC: 0xdeaf1eed, lock: &file_systems_lock
	RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic");

	// &lock->raw_lock: &(&file_systems_lock)->raw_lock
	arch_read_lock(&lock->raw_lock);
}

spinlock.h::arch_read_lock()

  • call: start_kernel()
  • vfs_caches_init()
  • kmem_cache_create(): names_cache
  • dcache_init()
  • inode_init()
  • files_init()
  • mnt_init()
  • call: mnt_init()

    • kmem_cache_create()
    • alloc_large_system_hash() : mnt_cache
    • alloc_large_system_hash() : Mount-cache
    • alloc_large_system_hash() : Mountpoint-cache
    • INIT_HLIST_HEAD() : &mount_hashtable[u]
    • INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
    • sysfs_init()
    • kobject_create_and_add() : fs
    • init_rootfs()
    • init_mount_tree()
  • call: init_mount_tree()

  • get_fs_type 3994 ~/fs/namespace.c
  • call: __get_fs_type() 402 ~/fs/filesystems.c
  • __get_fs_type()
  • call: __get_fs_type()

    • read_lock(): _raw_read_lock()
  • call: _raw_read_lock()

    • __raw_read_lock();
  • call: __raw_read_lock()

    • preempt_disable()
    • rwlock_acquire_read()
    • LOCK_CONTENDED(): do_raw_read_lock()
  • call: do_raw_read_lock()

    • RWLOCK_BUG_ON()
    • arch_read_lock()
// ARM10C 20160326
// &lock->raw_lock: &(&file_systems_lock)->raw_lock
static inline void arch_read_lock(arch_rwlock_t *rw)
{
	unsigned long tmp, tmp2;

	// &rw->lock: &(&(&file_systems_lock)->raw_lock)->lock
	prefetchw(&rw->lock);

// 2016/03/26 종료

	// prefetchw에서 한일:
	// &(&(&file_systems_lock)->raw_lock)->lock 의 값을 미리 cache에 가져옴

	// "1:  ldrex   tmp, [&rw->lock]\n"
	// "    adds    tmp, tmp, #1\n"
	// "    strexpl tmp2, tmp, [&rw->lock]\n"
	//      WFE("mi")
	// "    rsbpls   tmp, tmp2, #0\n"
	// "    bmi      1b"

	__asm__ __volatile__(
"1:	ldrex	%0, [%2]\n"
"	adds	%0, %0, #1\n"
"	strexpl	%1, %0, [%2]\n"
	WFE("mi")
"	rsbpls	%0, %1, #0\n"
"	bmi	1b"
	: "=&r" (tmp), "=&r" (tmp2)
	: "r" (&rw->lock)
	: "cc");

	smp_mb();
}

filesystem.c::__get_fs_type()

  • call: start_kernel()
  • vfs_caches_init()
  • kmem_cache_create(): names_cache
  • dcache_init()
  • inode_init()
  • files_init()
  • mnt_init()
  • call: mnt_init()

    • kmem_cache_create()
    • alloc_large_system_hash() : mnt_cache
    • alloc_large_system_hash() : Mount-cache
    • alloc_large_system_hash() : Mountpoint-cache
    • INIT_HLIST_HEAD() : &mount_hashtable[u]
    • INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
    • sysfs_init()
    • kobject_create_and_add() : fs
    • init_rootfs()
    • init_mount_tree()
  • call: init_mount_tree()

  • get_fs_type 3994 ~/fs/namespace.c
  • call: __get_fs_type() 402 ~/fs/filesystems.c
  • __get_fs_type()
  • call: __get_fs_type()

    • read_lock(): _raw_read_lock()
  • call: _raw_read_lock()

    • __raw_read_lock();
  • call: __raw_read_lock()

    • preempt_disable()
    • rwlock_acquire_read()
    • LOCK_CONTENDED(): do_raw_read_lock()
  • call: do_raw_read_lock()

    • RWLOCK_BUG_ON()
    • arch_read_lock()

static inline void __raw_read_unlock(rwlock_t *lock)
{
	rwlock_release(&lock->dep_map, 1, _RET_IP_);
	do_raw_read_unlock(lock);
	preempt_enable();
}

  • call: __raw_read_unlock()
  • rwlock_release()
  • do_raw_read_unlock()
  • preempt_enable()
  • call: preempt_enable()
// ARM10C 20141206
#define preempt_enable() \
do { \
	barrier(); \
	if (unlikely(preempt_count_dec_and_test())) \
		__preempt_schedule(); \
} while (0)
  • call preempt_count_dec_and_test()
// ARM10C 20140614
#define preempt_count_dec_and_test() ({ preempt_count_sub(1); should_resched(); })
  • call preeempt_count_dec_and_test()
  • preempt_count_sub()
  • should_reshced()
// ARM10C 20130907
void __kprobes preempt_count_sub(int val)
{
#ifdef CONFIG_DEBUG_PREEMPT
	/*
	 * Underflow?
	 */
	if (DEBUG_LOCKS_WARN_ON(val > preempt_count()))
		return;
	/*
	 * Is the spinlock portion underflowing?
	 */
	if (DEBUG_LOCKS_WARN_ON((val < PREEMPT_MASK) &&
			!(preempt_count() & PREEMPT_MASK)))
		return;
#endif

	if (preempt_count() == val)
		trace_preempt_on(CALLER_ADDR0, get_parent_ip(CALLER_ADDR1));
	__preempt_count_sub(val);
}
EXPORT_SYMBOL(preempt_count_sub);
  • call: preempt_count_sub()
  • __preempt_count_sub()
  • call: preempt_count_sub()
static __always_inline void __preempt_count_sub(int val)
{
	*preempt_count_ptr() -= val;
}
  • return: __preempt_count_sub()

  • call preempt_count_dec_and_test()

    • preempt_count_sub(1);
    • should_resched();
  • call: should_resched()

static __always_inline bool should_resched(void)
{
	return unlikely(!preempt_count() && tif_need_resched());
}
  • call should_reched()
  • preempt_count()
  • tif_need_reched()
#define tif_need_resched() test_thread_flag(TIF_NEED_RESCHED)
  • call: tif_need_reched(): test_thread_flag()
#define test_thread_flag(flag)					\
	test_ti_thread_flag(current_thread_info(), flag)
static inline int test_ti_thread_flag(struct thread_info *ti, int flag)
{
	// flag: 1, &ti->flags: &init_thread_union.thread_info.flags
	return test_bit(flag, (unsigned long *)&ti->flags);
}

tif_need_reched(): 0

  • call: __get_fs_type()
// ARM10C 20160326
// name: "rootfs", len: 6
static struct file_system_type *__get_fs_type(const char *name, int len)
{
	struct file_system_type *fs;

	read_lock(&file_systems_lock);
	fs = *(find_filesystem(name, len));
	if (fs && !try_module_get(fs->owner))
		fs = NULL;
	read_unlock(&file_systems_lock);
	return fs;
}
  • return: get_fs_type()
// ARM10C 20160326
// "rootfs"
struct file_system_type *get_fs_type(const char *name)
{
	struct file_system_type *fs;

	// name: "rootfs", strchr("rootfs". '.'): NULL
	const char *dot = strchr(name, '.');
	// dot: NULL

	// dot: NULL, name: "rootfs", strlen("rootfs"): 6
	int len = dot ? dot - name : strlen(name);
	// len: 6

	// name: "rootfs", len: 6
	fs = __get_fs_type(name, len);
	if (!fs && (request_module("fs-%.*s", len, name) == 0))
		fs = __get_fs_type(name, len);
  • call get_fs_type()
  • strchr()
  • strlen
  • __get_fs_type()
  • request_module()
#define request_module(mod...) __request_module(true, mod)
  • call get_fs_type()
  • strchr()
  • strlen
  • __get_fs_type()
  • request_module() : __request_module()
int __request_module(bool wait, const char *fmt, ...)
{
	va_list args;
	char module_name[MODULE_NAME_LEN];
	unsigned int max_modprobes;
	int ret;
	static atomic_t kmod_concurrent = ATOMIC_INIT(0);
#define MAX_KMOD_CONCURRENT 50	/* Completely arbitrary value - KAO */
	static int kmod_loop_msg;

	/*
	 * We don't allow synchronous module loading from async.  Module
	 * init may invoke async_synchronize_full() which will end up
	 * waiting for this task which already is waiting for the module
	 * loading to complete, leading to a deadlock.
	 */
	WARN_ON_ONCE(wait && current_is_async());
  • current_is_async()
bool current_is_async(void)
{
	struct worker *worker = current_wq_worker();

log

f4215c8..8806bfe  master     -> origin/master
Updating f4215c8..8806bfe
Fast-forward
Reference/Breakdown/001_linux-kernel_20130428.md   |   2 +-
Reference/Breakdown/002_linux-kernel_20130504.md   |   4 +-
Reference/Breakdown/003_linux-kernel_20130511.md   |  51 ++++++
Reference/Breakdown/004_linux-kernel_20130518.md   | 200 +++++++++++++++++++++
Reference/Breakdown/005_linux-kernel_20130525.md   |  35 ++++
Reference/Breakdown/Figures/004_ARM_Inst.png       | Bin 0 -> 86235 bytes
Reference/Breakdown/Figures/004_ARM_Roadmap.jpeg   | Bin 0 -> 63610 bytes
Reference/Breakdown/Figures/004_ARM_Stack.jpg      | Bin 0 -> 24493 bytes
.../Breakdown/Figures/004_ARMv8_Architecture.png   | Bin 0 -> 679624 bytes
Reference/Breakdown/Figures/004_Exynos5_OCTA.png   | Bin 0 -> 91189 bytes
.../Breakdown/Figures/004_Intel_Nehalem_arch.png   | Bin 0 -> 126640 bytes
Reference/Breakdown/Figures/004_alias.gif          | Bin 0 -> 4207 bytes
Reference/Breakdown/Figures/004_loopunroll.png     | Bin 0 -> 469092 bytes
Reference/Breakdown/Figures/004_m7_overview.JPG    | Bin 0 -> 679993 bytes
.../Breakdown/Figures/004_perf_loopunroll.png      | Bin 0 -> 12556 bytes
arch/arm/include/asm/atomic.h                      |   7 +
arch/arm/include/asm/barrier.h                     |   2 +
arch/arm/include/asm/processor.h                   |  17 ++
arch/arm/include/asm/spinlock.h                    |  48 +++++
arch/arm/include/asm/thread_info.h                 |   4 +
arch/arm/include/asm/unified.h                     |   1 +
fs/filesystems.c                                   |  41 ++++-
include/acpi/platform/acenv.h                      |   6 +
include/asm-generic/bug.h                          |   1 +
include/asm-generic/current.h                      |   1 +
include/asm-generic/preempt.h                      |   8 +
include/linux/compiler-gcc.h                       |   1 +
include/linux/debug_locks.h                        |   1 +
include/linux/fs.h                                 |   1 +
include/linux/gfp.h                                |   1 +
include/linux/kmod.h                               |  13 +-
include/linux/lockdep.h                            |   4 +-
include/linux/module.h                             |   4 +
include/linux/moduleparam.h                        |   1 +
include/linux/preempt.h                            |   3 +
include/linux/preempt_mask.h                       |   1 +
include/linux/rwlock.h                             |   1 +
include/linux/rwlock_api_smp.h                     |  27 ++-
include/linux/rwlock_types.h                       |   1 +
include/linux/sched.h                              |   3 +
include/linux/security.h                           |   2 +
include/linux/slab.h                               |   4 +
include/linux/thread_info.h                        |   7 +
include/linux/types.h                              |   1 +
include/linux/workqueue.h                          |   8 +
include/trace/events/module.h                      |   2 +
init/do_mounts.c                                   |   1 +
init/init_task.c                                   |   1 +
kernel/async.c                                     |   5 +
kernel/fork.c                                      |   1 +
kernel/kmod.c                                      | 131 +++++++++++++-
kernel/locking/spinlock.c                          |  15 ++
kernel/locking/spinlock_debug.c                    |  18 ++
kernel/module.c                                    |   7 +
kernel/sched/core.c                                |  12 +-
kernel/workqueue_internal.h                        |   3 +
lib/vsprintf.c                                     |   2 +
mm/util.c                                          |   2 +
58 files changed, 702 insertions(+), 10 deletions(-)
create mode 100644 Reference/Breakdown/003_linux-kernel_20130511.md
create mode 100644 Reference/Breakdown/004_linux-kernel_20130518.md
create mode 100644 Reference/Breakdown/005_linux-kernel_20130525.md
create mode 100644 Reference/Breakdown/Figures/004_ARM_Inst.png
create mode 100644 Reference/Breakdown/Figures/004_ARM_Roadmap.jpeg
create mode 100644 Reference/Breakdown/Figures/004_ARM_Stack.jpg
create mode 100644 Reference/Breakdown/Figures/004_ARMv8_Architecture.png
create mode 100644 Reference/Breakdown/Figures/004_Exynos5_OCTA.png
create mode 100644 Reference/Breakdown/Figures/004_Intel_Nehalem_arch.png
create mode 100644 Reference/Breakdown/Figures/004_alias.gif
create mode 100644 Reference/Breakdown/Figures/004_loopunroll.png
create mode 100644 Reference/Breakdown/Figures/004_m7_overview.JPG
create mode 100644 Reference/Breakdown/Figures/004_perf_loopunroll.png