135주차 (2016.03.05) vfs_caches_init()


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

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

135 주차 진도

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

  • mnt_alloc_id()

  • start_kernel 1 ~/init/main.c
  • vfs_caches_init 925 ~/init/main.c
  • mnt_init 3807 ~/fs/dcache.c
  • kobject_create_and_add 4028 ~/fs/namespace.c
  • kobject_add 1124 ~/lib/kobject.c
  • kobject_add_varg 683 ~/lib/kobject.c
  • kobject_add_internal 577 ~/lib/kobject.c
  • create_dir 335 ~/lib/kobject.c
  • sysfs_new_dirent 977 sd = sysfs_new_dirent(name, mode, SYSFS_DIR);start_kernel 1 ~/init/main.c
  • 134주차 함수 호출 구조
  • 주석이 잘못 된부분을 발견해서 sysfs_init()를 수정.
  • call: start_kernel()
  • vfs_caches_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()
  • call: kobject_create_adn_add(): fs

  • 수정된 주석.
  • kobject_create()
  • kobject_add()
  • call: kobject_add()
  • va_start()
  • kobject_add_varg()
  • call: kobject_add_varg()
  • kobject_set_name_vargs()
  • kobject_add_internal()
  • call: kobject_add_internal()
  • kobject_get()
  • 여기서 주석 수정
  • create_dir()
  • return: kobject_add_varg()
  • return: kobject_add_internal() -> kobject_add_varg()
  • kobject_set_name_vargs()
  • kobject_add_internal()
  • return: kobejct_add()
  • return: kobject_add() <- kobject_add_varg() <- kobject_add_internal()
  • va_start()
  • return: kobject_add_varg()
    • 주석 수정했음.
  • va_end()
  • return: kobject_create_and_add() <- kobject_add() <- kobject_add_varg() <- kobject_add_internal()
  • kobject_set_name_vargs()
  • kobject_add()
  • return: mnt_init()
  • retrun: 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()
    • return: kobject_create_and_add() : fs
      • kobject_create_and_add() <- kobject_add() <- kobject_add_varg() <- kobject_add_internal()
    • init_rootfs()
  • call: init_rootfs()

    • register_filesystem()
    • shmem_init()
  • call: shmem_init()

    • bdi_init()
    • shmem_init_inodecache()
    • register_filesystem()
    • kern_mount(): kern_mount_data(): shmem_fs_type
  • call: kern_mount_data()

    • vfs_kern_mount()
  • call: vfs_kern_mount()

    • alloc_vfsmnt()
    • mount_fs()
    • lock_mount_hash()
    • list_add_tail()
    • unlock_mount_hash()

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

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

	// 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를 연결함

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

do_mounts.c::init_rootfs()

  • call: start_kernel()

    • vfs_caches_init()
  • call: start_kernel()->vfs_caches_init()

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

    • kmem_cache_create(): 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()
// ARM10C 20160123
int __init init_rootfs(void)
{
	// register_filesystem(&rootfs_fs_type): 0
	int err = register_filesystem(&rootfs_fs_type);
	// err: 0

	// register_filesystem에서 한일:
	// (&sysfs_fs_type)->next: &rootfs_fs_type

	// err: 0
	if (err)
		return err;

	// CONFIG_TMPFS: y, IS_ENABLED(CONFIG_TMPFS): 1, saved_root_name[0]: 0,
	// root_fs_names: NULL, strstr(NULL, "tmpfs"): NULL
	if (IS_ENABLED(CONFIG_TMPFS) && !saved_root_name[0] &&
		(!root_fs_names || strstr(root_fs_names, "tmpfs"))) {
		err = shmem_init();

shmem.c::shmem_init()

  • call: start_kernel()

    • vfs_caches_init()
  • call: start_kernel()->vfs_caches_init()

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

    • kmem_cache_create(): 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()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()

    • register_filesystem(): rootfs_fs_type
    • shmem_init()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()->shmem_init()

    • bdi_init(): shmem_backing_dev_info
    • shmem_init_inodecache()
    • register_filesystem(): shmem_fs_type
    • kern_mount(): shmem_fs_type
// ARM10C 20160123
int __init shmem_init(void)
{
	int error;

	/* If rootfs called this, don't re-init */
	// shmem_inode_cachep: NULL
	if (shmem_inode_cachep)
		return 0;

	// bdi_init(&shmem_backing_dev_info): 0
	error = bdi_init(&shmem_backing_dev_info);
	// error: 0

	// error: 0
	if (error)
		goto out4;

	// shmem_init_inodecache(): 0
	error = shmem_init_inodecache();
	// error: 0

	// shmem_init_inodecache에서 한일:
	// struct shmem_inode_info 의 type의 메모리 할당하는 kmem_cache를 생성함
	// shmem_inode_cachep: kmem_cache#0

	// error: 0
	if (error)
		goto out3;

	// register_filesystem(&shmem_fs_type): 0
	error = register_filesystem(&shmem_fs_type);
	// error: 0

	// register_filesystem에서 한일:
	// (&rootfs_fs_type)->next: &shmem_fs_type

	// error: 0
	if (error) {
		printk(KERN_ERR "Could not register tmpfs\n");
		goto out2;
	}

	shm_mnt = kern_mount(&shmem_fs_type);

fs.h::kern_mount()

  • call: start_kernel()

    • vfs_caches_init()
  • call: start_kernel()->vfs_caches_init()

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

    • kmem_cache_create(): 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()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()

    • register_filesystem(): rootfs_fs_type
    • shmem_init()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()->shmem_init()

    • bdi_init(): shmem_backing_dev_info
    • shmem_init_inodecache()
    • register_filesystem(): shmem_fs_type
    • kern_mount(): shmem_fs_type
// ARM10C 20151031
// &sysfs_fs_type
#define kern_mount(type) kern_mount_data(type, NULL)

namespace.c::kern_mount_data()

  • call: start_kernel()

    • vfs_caches_init()
  • call: start_kernel()->vfs_caches_init()

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

    • kmem_cache_create(): 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()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()

    • register_filesystem(): rootfs_fs_type
    • shmem_init()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()->shmem_init()

    • bdi_init(): shmem_backing_dev_info
    • shmem_init_inodecache()
    • register_filesystem(): shmem_fs_type
    • kern_mount(): shmem_fs_type :: kern_mount_data()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()->shmem_init()->kern_mount_data()

    • vfs_kern_mount()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()->shmem_init()->kern_mount_data()->vfs_kern_mount()

// ARM10C 20151031
// &sysfs_fs_type, NULL
struct vfsmount *kern_mount_data(struct file_system_type *type, void *data)
{
	struct vfsmount *mnt;

	// type: &sysfs_fs_type, MS_KERNMOUNT: 0x400000, type->name: (&sysfs_fs_type)->name: "sysfs", data: NULL
	// vfs_kern_mount(&sysfs_fs_type, 0x400000, "sysfs", NULL): &(kmem_cache#2-oX (struct mount))->mnt
	mnt = vfs_kern_mount(type, MS_KERNMOUNT, type->name, data);

namespace.c::vfs_kern_mount()

  • call: start_kernel()

    • vfs_caches_init()
  • call: start_kernel()->vfs_caches_init()

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

    • kmem_cache_create(): 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()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()

    • register_filesystem(): rootfs_fs_type
    • shmem_init()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()->shmem_init()

    • bdi_init(): shmem_backing_dev_info
    • shmem_init_inodecache()
    • register_filesystem(): shmem_fs_type
    • kern_mount(): shmem_fs_type :: kern_mount_data()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()->shmem_init()->kern_mount_data()

    • vfs_kern_mount()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()->shmem_init()->kern_mount_data()->vfs_kern_mount()

// ARM10C 20151031
// type: &sysfs_fs_type, MS_KERNMOUNT: 0x400000, type->name: (&sysfs_fs_type)->name: "sysfs", data: NULL
struct vfsmount *
vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)
{
	struct mount *mnt;
	struct dentry *root;

	// type: &sysfs_fs_type
	if (!type)
		return ERR_PTR(-ENODEV);

	// name: "sysfs", alloc_vfsmnt("sysfs"): kmem_cache#2-oX (struct mount)
	mnt = alloc_vfsmnt(name);

namespace.c::alloc_vfsmnt()

  • call: start_kernel()

    • vfs_caches_init()
  • call: start_kernel()->vfs_caches_init()

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

    • kmem_cache_create(): 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()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()

    • register_filesystem(): rootfs_fs_type
    • shmem_init()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()->shmem_init()

    • bdi_init(): shmem_backing_dev_info
    • shmem_init_inodecache()
    • register_filesystem(): shmem_fs_type
    • kern_mount(): shmem_fs_type :: kern_mount_data()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()->shmem_init()->kern_mount_data()

    • vfs_kern_mount()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()->shmem_init()->kern_mount_data()->vfs_kern_mount()

// ARM10C 20151031
// name: "sysfs"
static struct mount *alloc_vfsmnt(const char *name)
{
	// mnt_cache: kmem_cache#2, GFP_KERNEL: 0xD0
	// kmem_cache_zalloc(kmem_cache#2, 0xD0): kmem_cache#2-oX (struct mount)
	struct mount *mnt = kmem_cache_zalloc(mnt_cache, GFP_KERNEL);
	// mnt: kmem_cache#2-oX (struct mount)

	// mnt: kmem_cache#2-oX (struct mount)
	if (mnt) {
		int err;

		// mnt: kmem_cache#2-oX (struct mount)
		// mnt_alloc_id(kmem_cache#2-oX (struct mount)): 0
		err = mnt_alloc_id(mnt);

namespace.c::mnt_alloc_id()

  • call: start_kernel()

    • vfs_caches_init()
  • call: start_kernel()->vfs_caches_init()

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

    • kmem_cache_create(): 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()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()

    • register_filesystem(): rootfs_fs_type
    • shmem_init()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()->shmem_init()

    • bdi_init(): shmem_backing_dev_info
    • shmem_init_inodecache()
    • register_filesystem(): shmem_fs_type
    • kern_mount(): shmem_fs_type :: kern_mount_data()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()->shmem_init()->kern_mount_data()

    • vfs_kern_mount()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()->shmem_init()->kern_mount_data()->vfs_kern_mount()

    • alloc_vfsmnt()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()->shmem_init()->kern_mount_data()->vfs_kern_mount()->alloc_vfsmnt()

    • kmem_cache_zalloc()
    • mnt_alloc_id()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()->shmem_init()->kern_mount_data()->vfs_kern_mount()->alloc_vfsmnt()->mnt_alloc_id()

// ARM10C 20160213
// mnt: kmem_cache#2-oX
static int mnt_alloc_id(struct mount *mnt)
{
	int res;

retry:
	// GFP_KERNEL: 0xD0
	// GFP_KERNEL: 0xD0
	ida_pre_get(&mnt_id_ida, GFP_KERNEL);

	spin_lock(&mnt_id_lock);

	// spin_lock에서 한일:
	// &mnt_id_lock을 이용한 spin lock 수행

	// spin_lock에서 한일:
	// &mnt_id_lock을 이용한 spin lock 수행

	// mnt_id_start: 0, &mnt->mnt_id: &(kmem_cache#2-oX)->mnt_id
	// ida_get_new_above(&mnt_id_ida, 0, &(kmem_cache#2-oX)->mnt_id): 0
	// mnt_id_start: 1, &mnt->mnt_id: &(kmem_cache#2-oX)->mnt_id
	res = ida_get_new_above(&mnt_id_ida, mnt_id_start, &mnt->mnt_id);
	// res: 0

	// ida_get_new_above에서 한일:
	// (&(&mnt_id_ida)->idr)->id_free: NULL
	// (&(&mnt_id_ida)->idr)->id_free_cnt: 6
	// (&(&mnt_id_ida)->idr)->top: kmem_cache#21-o7 (struct idr_layer)
	// (&(&mnt_id_ida)->idr)->layers: 1
	// (&mnt_id_ida)->free_bitmap: NULL
	//
	// (kmem_cache#21-o7 (struct idr_layer))->ary[0]: NULL
	// (kmem_cache#21-o7 (struct idr_layer))->layer: 0
	// (kmem_cache#21-o7 (struct idr_layer))->ary[0]: kmem_cache#27-oX (struct ida_bitmap)
	// (kmem_cache#21-o7 (struct idr_layer))->count: 1
	//
	// (kmem_cache#27-oX (struct ida_bitmap))->bitmap 의 0 bit를 1로 set 수행
	//
	// (kmem_cache#2-oX (struct mount))->mnt_id: 0

	// res: 0
	if (!res)
		// mnt_id_start: 0, mnt->mnt_id: (kmem_cache#2-oX)->mnt_id: 0
		mnt_id_start = mnt->mnt_id + 1;
		// mnt_id_start: 1

	spin_unlock(&mnt_id_lock);

	// spin_unlock에서 한일:
	// &mnt_id_lock을 이용한 spin unlock 수행

	// res: 0, EAGAIN: 11
	if (res == -EAGAIN)
		goto retry;

	// res: 0
	return res;
	// return 0
}

namespace.c::ida_pre_get()

  • call: start_kernel()

    • vfs_caches_init()
  • call: start_kernel()->vfs_caches_init()

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

    • kmem_cache_create(): 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()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()

    • register_filesystem(): rootfs_fs_type
    • shmem_init()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()->shmem_init()

    • bdi_init(): shmem_backing_dev_info
    • shmem_init_inodecache()
    • register_filesystem(): shmem_fs_type
    • kern_mount(): shmem_fs_type :: kern_mount_data()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()->shmem_init()->kern_mount_data()

    • vfs_kern_mount()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()->shmem_init()->kern_mount_data()->vfs_kern_mount()

    • alloc_vfsmnt()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()->shmem_init()->kern_mount_data()->vfs_kern_mount()->alloc_vfsmnt()

    • kmem_cache_zalloc()
    • mnt_alloc_id()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()->shmem_init()->kern_mount_data()->vfs_kern_mount()->alloc_vfsmnt()->mnt_alloc_id()

    • ida_pre_get()
// ARM10C 20160213
// &mnt_id_ida, GFP_KERNEL: 0xD0
int ida_pre_get(struct ida *ida, gfp_t gfp_mask)
{
	/* allocate idr_layers */
	// &ida->idr: &(&mnt_id_ida)->idr, gfp_mask: 0xD0
	// __idr_pre_get(&(&mnt_id_ida)->idr, 0xD0): 1
	// &ida->idr: &(&unnamed_dev_ida)->idr, gfp_mask: 0x20
	// __idr_pre_get(&(&unnamed_dev_ida)->idr, 0x20): 1
	// &ida->idr: &(&mnt_id_ida)->idr, gfp_mask: 0xD0
	// __idr_pre_get(&(&mnt_id_ida)->idr, 0xD0): 1
	if (!__idr_pre_get(&ida->idr, gfp_mask))
		return 0;

	// __idr_pre_get에서 한일:
	// idr_layer_cache를 사용하여 struct idr_layer 의 메모리 kmem_cache#21-o0...7를 8 개를 할당 받음
	// (kmem_cache#21-o0...7)->ary[0]: NULL
	// (&(&mnt_id_ida)->idr)->id_free: kmem_cache#21-o7
	// (&(&mnt_id_ida)->idr)->id_free_cnt: 7

	// __idr_pre_get에서 한일:
	// idr_layer_cache를 사용하여 struct idr_layer 의 메모리 kmem_cache#21-o0...7를 8 개를 할당 받음
	// (kmem_cache#21-o0...7)->ary[0]: NULL
	// (&(&unnamed_dev_ida)->idr)->id_free: kmem_cache#21-o7
	// (&(&unnamed_dev_ida)->idr)->id_free_cnt: 7

	// __idr_pre_get에서 한일:
	// idr_layer_cache를 사용하여 struct idr_layer 의 메모리 kmem_cache#21-oX 를 1 개를 할당 받음
	// (kmem_cache#21-oX (struct idr_layer))->ary[0]: NULL
	// (&(&mnt_id_ida)->idr)->id_free: kmem_cache#21-oX (struct idr_layer)
	// (&(&mnt_id_ida)->idr)->id_free_cnt: 8

	/* allocate free_bitmap */
	// ida->free_bitmap: (&mnt_id_ida)->free_bitmap: NULL
	// ida->free_bitmap: (&unnamed_dev_ida)->free_bitmap: NULL
	// ida->free_bitmap: (&mnt_id_ida)->free_bitmap: kmem_cache#27-oX (struct ida_bitmap)
	if (!ida->free_bitmap) {
		struct ida_bitmap *bitmap;

		// sizeof(struct ida_bitmap): 172 bytes, gfp_mask: 0xD0
		// kmalloc(172, 0xD0): kmem_cache#27-oX
		// sizeof(struct ida_bitmap): 172 bytes, gfp_mask: 0x20
		// kmalloc(172, 0x20): kmem_cache#27-oX
		bitmap = kmalloc(sizeof(struct ida_bitmap), gfp_mask);
		// bitmap: kmem_cache#27-oX
		// bitmap: kmem_cache#27-oX

		// bitmap: kmem_cache#27-oX
		// bitmap: kmem_cache#27-oX
		if (!bitmap)
			return 0;

		// ida: &mnt_id_ida, bitmap: kmem_cache#27-oX
		// ida: &unnamed_dev_ida, bitmap: kmem_cache#27-oX
		free_bitmap(ida, bitmap);

		// free_bitmap에서 한일:
		// (&mnt_id_ida)->free_bitmap: kmem_cache#27-oX

		// free_bitmap에서 한일:
		// (&unnamed_dev_ida)->free_bitmap: kmem_cache#27-oX
	}

	return 1;
	// return 1
	// return 1
	// return 1
}
EXPORT_SYMBOL(ida_pre_get);

idr.c::__idr_pre_get()

  • call: start_kernel()

    • vfs_caches_init()
  • call: start_kernel()->vfs_caches_init()

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

    • kmem_cache_create(): 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()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()

    • register_filesystem(): rootfs_fs_type
    • shmem_init()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()->shmem_init()

    • bdi_init(): shmem_backing_dev_info
    • shmem_init_inodecache()
    • register_filesystem(): shmem_fs_type
    • kern_mount(): shmem_fs_type :: kern_mount_data()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()->shmem_init()->kern_mount_data()

    • vfs_kern_mount()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()->shmem_init()->kern_mount_data()->vfs_kern_mount()

    • alloc_vfsmnt()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()->shmem_init()->kern_mount_data()->vfs_kern_mount()->alloc_vfsmnt()

    • kmem_cache_zalloc()
    • mnt_alloc_id()
  • call: start_kernel()->vfs_caches_init()->mnt_init()->init_rootfs()->shmem_init()->kern_mount_data()->vfs_kern_mount()->alloc_vfsmnt()->mnt_alloc_id()

    • ida_pre_get()
// ARM10C 20160213
// &ida->idr: &(&mnt_id_ida)->idr, gfp_mask: 0xD0
int __idr_pre_get(struct idr *idp, gfp_t gfp_mask)
{
	// idp->id_free_cnt: (&(&mnt_id_ida)->idr)->id_free_cnt: 0, MAX_IDR_FREE: 8
	// idp->id_free_cnt: (&(&unnamed_dev_ida)->idr)->id_free_cnt: 0, MAX_IDR_FREE: 8
	//
	// idp->id_free_cnt: (&(&mnt_id_ida)->idr)->id_free_cnt: 6, MAX_IDR_FREE: 8
	while (idp->id_free_cnt < MAX_IDR_FREE) {
		struct idr_layer *new;

		// idr_layer_cache: kmem_cache#21, gfp_mask: 0xD0
		// kmem_cache_zalloc(kmem_cache#21, 0xD0): kmem_cache#21-oX (struct idr_layer)
		// idr_layer_cache: kmem_cache#21, gfp_mask: 0x20
		// kmem_cache_zalloc(kmem_cache#21, 0x20): kmem_cache#21-oX (struct idr_layer)
		// idr_layer_cache: kmem_cache#21, gfp_mask: 0xD0
		// kmem_cache_zalloc(kmem_cache#21, 0xD0): kmem_cache#21-oX (struct idr_layer)
		new = kmem_cache_zalloc(idr_layer_cache, gfp_mask);
		// new: kmem_cache#21-oX (struct idr_layer)
		// new: kmem_cache#21-oX (struct idr_layer)
		// new: kmem_cache#21-oX (struct idr_layer)

		// new: kmem_cache#21-oX (struct idr_layer)
		// new: kmem_cache#21-oX (struct idr_layer)
		// new: kmem_cache#21-oX (struct idr_layer)
		if (new == NULL)
			return (0);

		// idp: &(&mnt_id_ida)->idr, new: kmem_cache#21-oX (struct idr_layer)
		// idp: &(&unnamed_dev_ida)->idr, new: kmem_cache#21-oX (struct idr_layer)
		// idp: &(&mnt_id_ida)->idr, new: kmem_cache#21-oX (struct idr_layer)
		move_to_free_list(idp, new);

		// move_to_free_list에서 한일:
		// (kmem_cache#21-oX)->ary[0]: NULL
		// (&(&mnt_id_ida)->idr)->id_free: kmem_cache#21-oX
		// (&(&mnt_id_ida)->idr)->id_free_cnt: 1

		// (&(&mnt_id_ida)->idr)->id_free_cnt: 2...8 까지 loop 수행

		// move_to_free_list에서 한일:
		// (kmem_cache#21-oX)->ary[0]: NULL
		// (&(&unnamed_dev_ida)->idr)->id_free: kmem_cache#21-oX
		// (&(&unnamed_dev_ida)->idr)->id_free_cnt: 1

		// (&(&unnamed_dev_ida)->idr)->id_free_cnt: 2...8 까지 loop 수행

		// move_to_free_list에서 한일:
		// (kmem_cache#21-oX)->ary[0]: NULL
		// (&(&mnt_id_ida)->idr)->id_free: kmem_cache#21-oX (struct idr_layer)
		// (&(&mnt_id_ida)->idr)->id_free_cnt: 8
	}
	return 1;
	// return 1
	// return 1
	// return 1
}
EXPORT_SYMBOL(__idr_pre_get);

  • move_to_free_list()
// ARM10C 20160213
// idp: &(&mnt_id_ida)->idr, new: kmem_cache#21-oX (struct idr_layer)
static void move_to_free_list(struct idr *idp, struct idr_layer *p)
{
	unsigned long flags;

	/*
	 * Depends on the return element being zeroed.
	 */
	// &idp->lock: &(&(&mnt_id_ida)->idr)->lock
	// &idp->lock: &(&(&mnt_id_ida)->idr)->lock
	spin_lock_irqsave(&idp->lock, flags);

	// spin_lock_irqsave에서 한일:
	// &(&(&mnt_id_ida)->idr)->lock을 사용하여 spin lock을 수행하고 cpsr을 flags에 저장함

	// spin_lock_irqsave에서 한일:
	// &(&(&mnt_id_ida)->idr)->lock을 사용하여 spin lock을 수행하고 cpsr을 flags에 저장함

	// idp: &(&mnt_id_ida)->idr, p: kmem_cache#21-oX (struct idr_layer)
	// idp: &(&mnt_id_ida)->idr, p: kmem_cache#21-oX (struct idr_layer)
	__move_to_free_list(idp, p);

	// __move_to_free_list에서 한일:
	// (kmem_cache#21-oX)->ary[0]: NULL
	// (&(&mnt_id_ida)->idr)->id_free: kmem_cache#21-oX (struct idr_layer)
	// (&(&mnt_id_ida)->idr)->id_free_cnt: 1

	// __move_to_free_list에서 한일:
	// (kmem_cache#21-oX)->ary[0]: NULL
	// (&(&mnt_id_ida)->idr)->id_free: kmem_cache#21-oX (struct idr_layer)
	// (&(&mnt_id_ida)->idr)->id_free_cnt: 8

	spin_unlock_irqrestore(&idp->lock, flags);

	// spin_unlock_irqrestore에서 한일:
	// &(&(&mnt_id_ida)->idr)->lock을 사용하여 spin unlock을 수행하고 flags에 저장된 cpsr을 복원

	// spin_unlock_irqrestore에서 한일:
	// &(&(&mnt_id_ida)->idr)->lock을 사용하여 spin unlock을 수행하고 flags에 저장된 cpsr을 복원
}
  • __move_to_free_list()
// ARM10C 20160213
// idp: &(&mnt_id_ida)->idr, p: kmem_cache#21-oX (struct idr_layer)
static void __move_to_free_list(struct idr *idp, struct idr_layer *p)
{
	// p->ary[0]: (kmem_cache#21-oX (struct idr_layer))->ary[0]: NULL, idp->id_free: (&(&mnt_id_ida)->idr)->id_free: NULL
	// p->ary[0]: (kmem_cache#21-oX (struct idr_layer))->ary[0]: NULL, idp->id_free: (&(&mnt_id_ida)->idr)->id_free: kmem_cache#21-oX (struct idr_layer)
	p->ary[0] = idp->id_free;
	// p->ary[0]: (kmem_cache#21-oX (struct idr_layer))->ary[0]: NULL
	// p->ary[0]: (kmem_cache#21-oX (struct idr_layer))->ary[0]: kmem_cache#21-oX (struct idr_layer)

	// idp->id_free: (&(&mnt_id_ida)->idr)->id_free: NULL, p: kmem_cache#21-oX (struct idr_layer)
	// idp->id_free: (&(&mnt_id_ida)->idr)->id_free: kmem_cache#21-oX (struct idr_layer), p: kmem_cache#21-oX (struct idr_layer)
	idp->id_free = p;
	// idp->id_free: (&(&mnt_id_ida)->idr)->id_free: kmem_cache#21-oX (struct idr_layer)
	// idp->id_free: (&(&mnt_id_ida)->idr)->id_free: kmem_cache#21-oX (struct idr_layer)

	// idp->id_free_cnt: (&(&mnt_id_ida)->idr)->id_free_cnt: 0
	// idp->id_free_cnt: (&(&mnt_id_ida)->idr)->id_free_cnt: 7
	idp->id_free_cnt++;
	// idp->id_free_cnt: (&(&mnt_id_ida)->idr)->id_free_cnt: 1
	// idp->id_free_cnt: (&(&mnt_id_ida)->idr)->id_free_cnt: 8
}
  • mnt_alloc_id()
// ARM10C 20160213
// mnt: kmem_cache#2-oX
static int mnt_alloc_id(struct mount *mnt)
{
	int res;

retry:
	// GFP_KERNEL: 0xD0
	// GFP_KERNEL: 0xD0
	ida_pre_get(&mnt_id_ida, GFP_KERNEL);

	// ida_pre_get에서 한일:
	// idr_layer_cache를 사용하여 struct idr_layer 의 메모리 kmem_cache#21-o0...7를 8 개를 할당 받음
	// (kmem_cache#21-o0...7)->ary[0]: NULL
	// (&(&mnt_id_ida)->idr)->id_free: kmem_cache#21-o7
	// (&(&mnt_id_ida)->idr)->id_free_cnt: 7
	//
	// struct ida_bitmap 의 메모리 kmem_cache#27-oX 할당 받음
	// (&mnt_id_ida)->free_bitmap: kmem_cache#27-oX

	// ida_pre_get에서 한일:
	// idr_layer_cache를 사용하여 struct idr_layer 의 메모리 kmem_cache#21-oX 를 1 개를 할당 받음
	// (kmem_cache#21-oX (struct idr_layer))->ary[0]: NULL
	// (&(&mnt_id_ida)->idr)->id_free: kmem_cache#21-oX (struct idr_layer)
	// (&(&mnt_id_ida)->idr)->id_free_cnt: 8

	spin_lock(&mnt_id_lock);

	// spin_lock에서 한일:
	// &mnt_id_lock을 이용한 spin lock 수행

	// spin_lock에서 한일:
	// &mnt_id_lock을 이용한 spin lock 수행

	// mnt_id_start: 0, &mnt->mnt_id: &(kmem_cache#2-oX)->mnt_id
	// ida_get_new_above(&mnt_id_ida, 0, &(kmem_cache#2-oX)->mnt_id): 0
	// mnt_id_start: 1, &mnt->mnt_id: &(kmem_cache#2-oX)->mnt_id
	res = ida_get_new_above(&mnt_id_ida, mnt_id_start, &mnt->mnt_id);
  • ida_get_new_above()
// ARM10C 20160213
// &mnt_id_ida, mnt_id_start: 1, &mnt->mnt_id: &(kmem_cache#2-oX)->mnt_id
int ida_get_new_above(struct ida *ida, int starting_id, int *p_id)
{
	// MAX_IDR_LEVEL: 4
	// MAX_IDR_LEVEL: 4
	struct idr_layer *pa[MAX_IDR_LEVEL + 1];
	struct ida_bitmap *bitmap;
	unsigned long flags;

	// starting_id: 0, IDA_BITMAP_BITS: 1344
	// starting_id: 1, IDA_BITMAP_BITS: 1344
	int idr_id = starting_id / IDA_BITMAP_BITS;
	// idr_id: 0
	// idr_id: 0

	// starting_id: 0, IDA_BITMAP_BITS: 1344
	// starting_id: 1, IDA_BITMAP_BITS: 1344
	int offset = starting_id % IDA_BITMAP_BITS;
	// offset: 0
	// offset: 1

	int t, id;

 restart:
	/* get vacant slot */
	// &ida->idr: &(&mnt_id_ida)->idr, idr_id: 0
	// idr_get_empty_slot(&(&mnt_id_ida)->idr, 0, pa, 0, &(&mnt_id_ida)->idr): 0
	//
	// &ida->idr: &(&mnt_id_ida)->idr, idr_id: 0
	t = idr_get_empty_slot(&ida->idr, idr_id, pa, 0, &ida->idr);
  • idr_get_empty_slot()
// ARM10C 20160213
// &ida->idr: &(&mnt_id_ida)->idr, idr_id: 0, pa, 0, &ida->idr: &(&mnt_id_ida)->idr
static int idr_get_empty_slot(struct idr *idp, int starting_id,
			      struct idr_layer **pa, gfp_t gfp_mask,
			      struct idr *layer_idr)
{
	struct idr_layer *p, *new;
	int layers, v, id;
	unsigned long flags;

	// starting_id: 0
	// starting_id: 1
	id = starting_id;
	// id: 0
	// id: 1

build_up:
	// idp->top: (&(&mnt_id_ida)->idr)->top: NULL
	p = idp->top;
	// p: NULL

	// idp->layers: (&(&mnt_id_ida)->idr)->layers: 0
	layers = idp->layers;
	// layers: 0

	// p: NULL
	if (unlikely(!p)) {
		// gfp_mask: 0, layer_idr: &(&mnt_id_ida)->idr
		// idr_layer_alloc(0, &(&mnt_id_ida)->idr): kmem_cache#21-o7, p: kmem_cache#21-o7
		if (!(p = idr_layer_alloc(gfp_mask, layer_idr)))
			return -ENOMEM;

		// idr_layer_alloc에서 한일:
		// (&(&mnt_id_ida)->idr)->id_free: NULL
		// (&(&mnt_id_ida)->idr)->id_free_cnt: 6
		// (kmem_cache#21-o7)->ary[0]: NULL

		// p->layer: (kmem_cache#21-o7)->layer
		p->layer = 0;
		// p->layer: (kmem_cache#21-o7)->layer: 0

		// layers: 0
		layers = 1;
		// layers: 1
	}

// 2015/10/31 종료
// 2015/11/07 시작

	/*
	 * Add a new layer to the top of the tree if the requested
	 * id is larger than the currently allocated space.
	 */
	// id: 0, layers: 1, idr_max(1): 255
	while (id > idr_max(layers)) {
		layers++;
		if (!p->count) {
			/* special case: if the tree is currently empty,
			 * then we grow the tree by moving the top node
			 * upwards.
			 */
			p->layer++;
			WARN_ON_ONCE(p->prefix);
			continue;
		}
		if (!(new = idr_layer_alloc(gfp_mask, layer_idr))) {
			/*
			 * The allocation failed.  If we built part of
			 * the structure tear it down.
			 */
			spin_lock_irqsave(&idp->lock, flags);
			for (new = p; p && p != idp->top; new = p) {
				p = p->ary[0];
				new->ary[0] = NULL;
				new->count = 0;
				bitmap_clear(new->bitmap, 0, IDR_SIZE);
				__move_to_free_list(idp, new);
			}
			spin_unlock_irqrestore(&idp->lock, flags);
			return -ENOMEM;
		}
		new->ary[0] = p;
		new->count = 1;
		new->layer = layers-1;
		new->prefix = id & idr_layer_prefix_mask(new->layer);
		if (bitmap_full(p->bitmap, IDR_SIZE))
			__set_bit(0, new->bitmap);
		p = new;
	}

	// idp->top: (&(&mnt_id_ida)->idr)->top, p: kmem_cache#21-o7
	// __rcu_assign_pointer((&(&mnt_id_ida)->idr)->top, kmem_cache#21-o7, __rcu):
	// do {
	//      smp_wmb();
	//      ((&(&mnt_id_ida)->idr)->top) = (typeof(*kmem_cache#21-o7) __force space *)(kmem_cache#21-o7);
	// } while (0)
	rcu_assign_pointer(idp->top, p);
	// ((&(&mnt_id_ida)->idr)->top): (typeof(*kmem_cache#21-o7) __force space *)(kmem_cache#21-o7)

	// idp->layers: (&(&mnt_id_ida)->idr)->layers, layers: 1
	idp->layers = layers;
	// idp->layers: (&(&mnt_id_ida)->idr)->layers: 1

	// idp: &(&mnt_id_ida)->idr, id: 0, pa, gfp_mask: 0, layer_idr: &(&mnt_id_ida)->idr
	// sub_alloc(&(&mnt_id_ida)->idr, &id, pa, 0, &(&mnt_id_ida)->idr): 0
	v = sub_alloc(idp, &id, pa, gfp_mask, layer_idr);
	// v: 0

	// sub_alloc에서 한일:
	// pa[0]: kmem_cache#21-o7 (struct idr_layer)

	// v: 0, EAGAIN: 11
	if (v == -EAGAIN)
		goto build_up;

	// v: 0
	return(v);
	// return 0
}

ida_get_new_above()

  • call: start_kernel()
  • vfs_caches_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()
  • call: init_rootfs()

    • register_filesystem()
    • shmem_init()
  • call: shmem_init()

    • bdi_init()
    • shmem_init_inodecache()
    • register_filesystem()
    • kern_mount(): kern_mount_data(): shmem_fs_type
  • call: kern_mount_data()

    • vfs_kern_mount()
  • call: vfs_kern_mount()

    • alloc_vfsmnt()
  • call: alloc_vfsmnt()

    • kmem_cache_zalloc(): GFP_KERNEL
    • mnt_alloc_id()
  • call: mnt_alloc_id()

    • ida_pre_get()
    • spin_lock()
    • res = ida_get_new_above(&mnt_id_ida, mnt_id_start, &mnt->mnt_id);
  • call ida_get_new_about()

    • idr_get_empth_slot()
    • spin_loc_irqsave()
    • spin_unloc_irqrestore()
    • rcu_assign_pointer()
    • find_next_zero_bit()
    • __set_bit()
// ARM10C 20160213
// &mnt_id_ida, mnt_id_start: 1, &mnt->mnt_id: &(kmem_cache#2-oX)->mnt_id
int ida_get_new_above(struct ida *ida, int starting_id, int *p_id)
{
	// MAX_IDR_LEVEL: 4
	struct idr_layer *pa[MAX_IDR_LEVEL + 1];
	struct ida_bitmap *bitmap;
	unsigned long flags;

	// starting_id: 1, IDA_BITMAP_BITS: 992
	int idr_id = starting_id / IDA_BITMAP_BITS;
	// idr_id: 0

	// starting_id: 1, IDA_BITMAP_BITS: 992
	int offset = starting_id % IDA_BITMAP_BITS;
	// offset: 1

	int t, id;

 restart:
	/* get vacant slot */
	// &ida->idr: &(&mnt_id_ida)->idr, idr_id: 0
	// idr_get_empty_slot(&(&mnt_id_ida)->idr, 0, pa, 0, &(&mnt_id_ida)->idr): 1
	t = idr_get_empty_slot(&ida->idr, idr_id, pa, 0, &ida->idr);
	// t: 1

	// idr_get_empty_slot에서 한일:
	// (&(&mnt_id_ida)->idr)->top: kmem_cache#21-o7
	// (&(&mnt_id_ida)->idr)->layers: 1
	// pa[0]: kmem_cache#21-o7 (struct idr_layer)

	// t: 1
	if (t < 0)
		return t == -ENOMEM ? -EAGAIN : t;

	// t: 1, IDA_BITMAP_BITS: 992, MAX_IDR_BIT: 0x80000000
	if (t * IDA_BITMAP_BITS >= MAX_IDR_BIT)
		return -ENOSPC;

	// t: 1, idr_id: 0
	if (t != idr_id)
		// offset: 1
		offset = 0;
		// offset: 0

	// idr_id: 0, t: 1
	idr_id = t;
	// idr_id: 1

	/* if bitmap isn't there, create a new one */

	// pa[0]: kmem_cache#21-o7 (struct idr_layer), idr_id: 1, IDR_MASK: 0xFF
	// pa[0]->ary[1]: (kmem_cache#21-o7 (struct idr_layer))->ary[1]: NULL
	bitmap = (void *)pa[0]->ary[idr_id & IDR_MASK];
	// bitmap: NULL

	// bitmap: NULL
	// bitmap: NULL
	if (!bitmap) {
		// &ida->idr.lock: &(&mnt_id_ida)->idr.lock
		// &ida->idr.lock: &(&mnt_id_ida)->idr.lock
		spin_lock_irqsave(&ida->idr.lock, flags);

		// spin_lock_irqsave에서 한일:
		// &(&(&mnt_id_ida)->idr)->lock을 사용하여 spin lock을 수행하고 cpsr을 flags에 저장함

		// spin_lock_irqsave에서 한일:
		// &(&(&mnt_id_ida)->idr)->lock을 사용하여 spin lock을 수행하고 cpsr을 flags에 저장함

		// ida->free_bitmap: (&mnt_id_ida)->free_bitmap: kmem_cache#27-oX (struct ida_bitmap)
		// ida->free_bitmap: (&mnt_id_ida)->free_bitmap: NULL
		bitmap = ida->free_bitmap;
		// bitmap: kmem_cache#27-oX (struct ida_bitmap)
		// bitmap: NULL

		// ida->free_bitmap: (&mnt_id_ida)->free_bitmap: kmem_cache#27-oX (struct ida_bitmap)
		// ida->free_bitmap: (&mnt_id_ida)->free_bitmap: NULL
		ida->free_bitmap = NULL;
		// ida->free_bitmap: (&mnt_id_ida)->free_bitmap: NULL
		// ida->free_bitmap: (&mnt_id_ida)->free_bitmap: NULL

		// &ida->idr.lock: &(&mnt_id_ida)->idr.lock
		// &ida->idr.lock: &(&mnt_id_ida)->idr.lock
		spin_unlock_irqrestore(&ida->idr.lock, flags);

		// spin_unlock_irqrestore에서 한일:
		// &(&(&mnt_id_ida)->idr)->lock을 사용하여 spin unlock을 수행하고 flags에 저장된 cpsr을 복원

		// spin_unlock_irqrestore에서 한일:
		// &(&(&mnt_id_ida)->idr)->lock을 사용하여 spin unlock을 수행하고 flags에 저장된 cpsr을 복원

		// bitmap: kmem_cache#27-oX (struct ida_bitmap)
		// bitmap: NULL
		if (!bitmap)
			// EAGAIN: 11
			return -EAGAIN;
			// return -11

		// bitmap: kmem_cache#27-oX (struct ida_bitmap)
		memset(bitmap, 0, sizeof(struct ida_bitmap));

		// memset에서 한일:
		// kmem_cache#27-oX (struct ida_bitmap) 메모리을 0으로 초기화

		// pa[0]: kmem_cache#21-o7 (struct idr_layer), idr_id: 0, IDR_MASK: 0xFF
		// pa[0]->ary[0]: (kmem_cache#21-o7 (struct idr_layer))->ary[0]: NULL
		// bitmap: kmem_cache#27-oX (struct ida_bitmap)
		// __rcu_assign_pointer((kmem_cache#21-o7 (struct idr_layer))->ary[0], kmem_cache#27-oX (struct ida_bitmap), __rcu):
		// do {
		//      smp_wmb();
		//      ((kmem_cache#21-o7 (struct idr_layer))->ary[0]) = (typeof(*kmem_cache#27-oX (struct ida_bitmap)) __force space *)(kmem_cache#27-oX (struct ida_bitmap));
		// } while (0)
		rcu_assign_pointer(pa[0]->ary[idr_id & IDR_MASK],
				(void *)bitmap);
		// ((kmem_cache#21-o7 (struct idr_layer))->ary[0]): (typeof(*kmem_cache#27-oX (struct ida_bitmap)) __force space *)(kmem_cache#27-oX (struct ida_bitmap))

		// pa[0]->count: (kmem_cache#21-o7 (struct idr_layer))->count: 0
		pa[0]->count++;
		// pa[0]->count: (kmem_cache#21-o7 (struct idr_layer))->count: 1
	}

	/* lookup for empty slot */
	// bitmap->bitmap: (kmem_cache#27-oX (struct ida_bitmap))->bitmap, IDA_BITMAP_BITS: 1344, offset: 0
	// find_next_zero_bit((kmem_cache#27-oX (struct ida_bitmap))->bitmap, 1344, 0): 0
	t = find_next_zero_bit(bitmap->bitmap, IDA_BITMAP_BITS, offset);
	// t: 0

	// t: 0, IDA_BITMAP_BITS: 1344
	if (t == IDA_BITMAP_BITS) {
		/* no empty slot after offset, continue to the next chunk */
		idr_id++;
		offset = 0;
		goto restart;
	}

	// idr_id: 0, IDA_BITMAP_BITS: 1344, t: 0
	id = idr_id * IDA_BITMAP_BITS + t;
	// id: 0

	// id: 0, MAX_IDR_BIT: 0x80000000
	if (id >= MAX_IDR_BIT)
		return -ENOSPC;

	// t: 0, bitmap->bitmap: (kmem_cache#27-oX (struct ida_bitmap))->bitmap
	__set_bit(t, bitmap->bitmap);

	// __set_bit에서 한일:
	// (kmem_cache#27-oX (struct ida_bitmap))->bitmap 의 0 bit를 1로 set 수행

	// bitmap->nr_busy: (kmem_cache#27-oX (struct ida_bitmap))->nr_busy: 1, IDA_BITMAP_BITS: 1344
	if (++bitmap->nr_busy == IDA_BITMAP_BITS)
		idr_mark_full(pa, idr_id);

	// *p_id: (kmem_cache#2-oX)->mnt_id, id: 0
	*p_id = id;
	// *p_id: (kmem_cache#2-oX)->mnt_id: 0

	/* Each leaf node can handle nearly a thousand slots and the
	 * whole idea of ida is to have small memory foot print.
	 * Throw away extra resources one by one after each successful
	 * allocation.
	 */
	// ida->idr.id_free_cnt: (&mnt_id_ida)->idr.id_free_cnt: 6, ida->free_bitmap: (&mnt_id_ida)->free_bitmap: NULL
	if (ida->idr.id_free_cnt || ida->free_bitmap) {
		// &ida->idr: &(&mnt_id_ida)->idr
		// get_from_free_list(&(&mnt_id_ida)->idr): NULL
		struct idr_layer *p = get_from_free_list(&ida->idr);
		// p: NULL

		// p: NULL
		if (p)
			kmem_cache_free(idr_layer_cache, p);
	}

	return 0;
	// return 0
}
EXPORT_SYMBOL(ida_get_new_above);

res = ida_get_new_above(&mnt_id_ida, mnt_id_start, &mnt->mnt_id);
  • call: start_kernel()
  • vfs_caches_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()
  • call: init_rootfs()

    • register_filesystem()
    • shmem_init()
  • call: shmem_init()

    • bdi_init()
    • shmem_init_inodecache()
    • register_filesystem()
    • kern_mount(): kern_mount_data(): shmem_fs_type
  • call: kern_mount_data()

    • vfs_kern_mount()
  • call: vfs_kern_mount()

    • alloc_vfsmnt()
  • call: alloc_vfsmnt()

    • kmem_cache_zalloc(): GFP_KERNEL
    • mnt_alloc_id()
  • call: mnt_alloc_id()

    • ida_pre_get()
    • spin_lock()
    • res = ida_get_new_above(&mnt_id_ida, mnt_id_start, &mnt->mnt_id);
  • call ida_get_new_about()

    • idr_get_empth_slot()
    • spin_loc_irqsave()
    • spin_unloc_irqrestore()
    • memset()
    • rcu_assign_pointer()
    • find_next_zero_bit()
    • __set_bit()
    • kmem_cache_free(): idr_layer_cache
DEFINE_EVENT(kmem_free, kmem_cache_free,

	TP_PROTO(unsigned long call_site, const void *ptr),

	TP_ARGS(call_site, ptr)
);
void kmem_cache_free(struct kmem_cache *cachep, void *objp)
{
	unsigned long flags;
	cachep = cache_from_obj(cachep, objp);
	if (!cachep)
		return;

	local_irq_save(flags);
	debug_check_no_locks_freed(objp, cachep->object_size);
	if (!(cachep->flags & SLAB_DEBUG_OBJECTS))
		debug_check_no_obj_freed(objp, cachep->object_size);
	__cache_free(cachep, objp, _RET_IP_);
	local_irq_restore(flags);

	trace_kmem_cache_free(_RET_IP_, objp);
}
EXPORT_SYMBOL(kmem_cache_free);

slab.h::kmem_cache_free()

  • call: start_kernel()
  • vfs_caches_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()
  • call: init_rootfs()

    • register_filesystem()
    • shmem_init()
  • call: shmem_init()

    • bdi_init()
    • shmem_init_inodecache()
    • register_filesystem()
    • kern_mount(): kern_mount_data(): shmem_fs_type
  • call: kern_mount_data()

    • vfs_kern_mount()
  • call: vfs_kern_mount()

    • alloc_vfsmnt()
  • call: alloc_vfsmnt()

    • kmem_cache_zalloc(): GFP_KERNEL
    • mnt_alloc_id()
  • call: mnt_alloc_id()

    • ida_pre_get()
    • spin_lock()
    • res = ida_get_new_above(&mnt_id_ida, mnt_id_start, &mnt->mnt_id);
  • call ida_get_new_about()

    • idr_get_empth_slot()
    • spin_loc_irqsave()
    • spin_unloc_irqrestore()
    • memset()
    • rcu_assign_pointer()
    • find_next_zero_bit()
    • __set_bit()
    • kmem_cache_free(): idr_layer_cache
  • call: kmem_cache_free()

    • cache_from_obj()
static inline struct kmem_cache *cache_from_obj(struct kmem_cache *s, void *x)
{
	struct kmem_cache *cachep;
	struct page *page;

	/*
	 * When kmemcg is not being used, both assignments should return the
	 * same value. but we don't want to pay the assignment price in that
	 * case. If it is not compiled in, the compiler should be smart enough
	 * to not do even the assignment. In that case, slab_equal_or_root
	 * will also be a constant.
	 */
	if (!memcg_kmem_enabled() && !unlikely(s->flags & SLAB_DEBUG_FREE))
		return s;

	page = virt_to_head_page(x);
	cachep = page->slab_cache;
	if (slab_equal_or_root(cachep, s))
		return cachep;

	pr_err("%s: Wrong slab cache. %s but object is from %s\n",
		__FUNCTION__, cachep->name, s->name);
	WARN_ON_ONCE(1);
	return s;
}
#endif
  • ᆭSLAB_PANIC을 이용하여 cache를 생성한다.
  • cache_from_obj()에서 flags값을 가져와서
  • virt_to_head_page()를 실행한다.
if (!memcg_kmem_enabled() && !unlikely(s->flags & SLAB_DEBUG_FREE))
    return s;
  • s->flags
  • (kmem_cache#21)->flags: XXX (SLAB_PANIC)
  • SLAB_DEBUG_FREE
#define SLAB_DEBUG_FREE		0x00000100UL	/* DEBUG: Perform (expensive) checks on free */
page = virt_to_head_page(x);
  • virt_to_head_page()
// ARM10C 20141129
// x: kmem_cache#30-o11
static inline struct page *virt_to_head_page(const void *x)
{
	// x: kmem_cache#30-o11, virt_to_page(kmem_cache#30-o11): kmem_cache#30-o11의 page 주소
	struct page *page = virt_to_page(x);
	// page: kmem_cache#30-o11의 page 주소

	// page: kmem_cache#30-o11의 page 주소
	// compound_head(kmem_cache#30-o11의 page 주소): kmem_cache#30-o11의 page 주소
	return compound_head(page);
	// return kmem_cache#30-o11의 page 주소
}

namespace.c::mnt_alloc_id()

  • call: start_kernel()
  • vfs_caches_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()
  • call: init_rootfs()

    • register_filesystem()
    • shmem_init()
  • call: shmem_init()

    • bdi_init()
    • shmem_init_inodecache()
    • register_filesystem()
    • kern_mount(): kern_mount_data(): shmem_fs_type
  • call: kern_mount_data()

    • vfs_kern_mount()
  • call: vfs_kern_mount()

    • alloc_vfsmnt()
  • call: alloc_vfsmnt()

    • kmem_cache_zalloc(): GFP_KERNEL
    • mnt_alloc_id()
  • call: mnt_alloc_id()

    • ida_pre_get()
    • spin_lock()
    • ida_get_new_above(&mnt_id_ida, mnt_id_start, &mnt->mnt_id);
    • spin_unlock
// ARM10C 20160213
// mnt: kmem_cache#2-oX
static int mnt_alloc_id(struct mount *mnt)
{
	int res;

retry:
	// GFP_KERNEL: 0xD0
	// GFP_KERNEL: 0xD0
	ida_pre_get(&mnt_id_ida, GFP_KERNEL);

	// ida_pre_get에서 한일:
	// idr_layer_cache를 사용하여 struct idr_layer 의 메모리 kmem_cache#21-o0...7를 8 개를 할당 받음
	//
	// (&(&mnt_id_ida)->idr)->id_free 이 idr object 8 번을 가르킴
	// |
	// |-> ---------------------------------------------------------------------------------------------------------------------------
	//     | idr object 8         | idr object 7         | idr object 6         | idr object 5         | .... | idr object 0         |
	//     ---------------------------------------------------------------------------------------------------------------------------
	//     | ary[0]: idr object 7 | ary[0]: idr object 6 | ary[0]: idr object 5 | ary[0]: idr object 4 | .... | ary[0]: NULL         |
	//     ---------------------------------------------------------------------------------------------------------------------------
	//
	// (&(&mnt_id_ida)->idr)->id_free: kmem_cache#21-oX (idr object 8)
	// (&(&mnt_id_ida)->idr)->id_free_cnt: 8
	//
	// struct ida_bitmap 의 메모리 kmem_cache#27-oX 할당 받음
	// (&mnt_id_ida)->free_bitmap: kmem_cache#27-oX (struct ida_bitmap)

	// ida_pre_get에서 한일:
	// idr_layer_cache를 사용하여 struct idr_layer 의 메모리 kmem_cache#21-oX 를 1 개를 할당 받음
	// (kmem_cache#21-oX (struct idr_layer))->ary[0]: NULL
	// (&(&mnt_id_ida)->idr)->id_free: kmem_cache#21-oX (struct idr_layer)
	// (&(&mnt_id_ida)->idr)->id_free_cnt: 8

	spin_lock(&mnt_id_lock);

	// spin_lock에서 한일:
	// &mnt_id_lock을 이용한 spin lock 수행

	// spin_lock에서 한일:
	// &mnt_id_lock을 이용한 spin lock 수행


// 2016/02/13 종료
// 2016/02/20 시작

	// mnt_id_start: 0, &mnt->mnt_id: &(kmem_cache#2-oX)->mnt_id
	// ida_get_new_above(&mnt_id_ida, 0, &(kmem_cache#2-oX)->mnt_id): 0
	// mnt_id_start: 1, &mnt->mnt_id: &(kmem_cache#2-oX)->mnt_id
	res = ida_get_new_above(&mnt_id_ida, mnt_id_start, &mnt->mnt_id);
	// res: 0

	// ida_get_new_above에서 한일:
	// (&(&mnt_id_ida)->idr)->id_free: NULL
	// (&(&mnt_id_ida)->idr)->id_free_cnt: 6
	// (&(&mnt_id_ida)->idr)->top: kmem_cache#21-o7 (struct idr_layer)
	// (&(&mnt_id_ida)->idr)->layers: 1
	// (&mnt_id_ida)->free_bitmap: NULL
	//
	// (kmem_cache#21-o7 (struct idr_layer))->ary[0]: NULL
	// (kmem_cache#21-o7 (struct idr_layer))->layer: 0
	// (kmem_cache#21-o7 (struct idr_layer))->ary[0]: kmem_cache#27-oX (struct ida_bitmap)
	// (kmem_cache#21-o7 (struct idr_layer))->count: 1
	//
	// (kmem_cache#27-oX (struct ida_bitmap))->bitmap 의 0 bit를 1로 set 수행
	//
	// (kmem_cache#2-oX (struct mount))->mnt_id: 0

	// res: 0
	if (!res)
		// mnt_id_start: 0, mnt->mnt_id: (kmem_cache#2-oX)->mnt_id: 0
		mnt_id_start = mnt->mnt_id + 1;
		// mnt_id_start: 1

	spin_unlock(&mnt_id_lock);

	// spin_unlock에서 한일:
	// &mnt_id_lock을 이용한 spin unlock 수행

	// res: 0, EAGAIN: 11
	if (res == -EAGAIN)
		goto retry;

	// res: 0
	return res;
	// return 0
}

namespace.c::alloc_vfsmnt()

  • call: start_kernel()
  • vfs_caches_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()
  • call: init_rootfs()

    • register_filesystem()
    • shmem_init()
  • call: shmem_init()

    • bdi_init()
    • shmem_init_inodecache()
    • register_filesystem()
    • kern_mount(): kern_mount_data(): shmem_fs_type
  • call: kern_mount_data()

    • vfs_kern_mount()
  • call: vfs_kern_mount()

    • alloc_vfsmnt()
  • call: alloc_vfsmnt()

    • kmem_cache_zalloc(): GFP_KERNEL
    • mnt_alloc_id()
    • kstrdup()
    • alloc_percpu()
    • this_cpu_add()
    • INIT_HLIST_NODE(): mnt_hash
    • INIT_LIST_HEAD(): mnt_child
    • INIT_LIST_HEAD(): mnt_mounts
    • INIT_LIST_HEAD(): mnt_list
    • INIT_LIST_HEAD(): mnt_expire
    • INIT_LIST_HEAD(): mnt_share
    • INIT_LIST_HEAD(): mnt_slave_list
    • INIT_LIST_HEAD_mnt_slave
    • INIT_HLIST_HEAD: mnt_fsnotify_marks
// ARM10C 20160213
// name: "tmpfs"
static struct mount *alloc_vfsmnt(const char *name)
{
	// mnt_cache: kmem_cache#2, GFP_KERNEL: 0xD0
	// kmem_cache_zalloc(kmem_cache#2, 0xD0): kmem_cache#2-oX (struct mount)
	// mnt_cache: kmem_cache#2, GFP_KERNEL: 0xD0
	// kmem_cache_zalloc(kmem_cache#2, 0xD0): kmem_cache#2-oX (struct mount)
	struct mount *mnt = kmem_cache_zalloc(mnt_cache, GFP_KERNEL);
	// mnt: kmem_cache#2-oX (struct mount)
	// mnt: kmem_cache#2-oX (struct mount)

	// mnt: kmem_cache#2-oX (struct mount)
	// mnt: kmem_cache#2-oX (struct mount)
	if (mnt) {
		int err;

		// mnt: kmem_cache#2-oX (struct mount)
		// mnt_alloc_id(kmem_cache#2-oX (struct mount)): 0
		// mnt: kmem_cache#2-oX (struct mount)
		// mnt_alloc_id(kmem_cache#2-oX (struct mount)): 0
		err = mnt_alloc_id(mnt);
		// err: 0

		// mnt_alloc_id에서 한일:
		// idr_layer_cache를 사용하여 struct idr_layer 의 메모리 kmem_cache#21-o0...7를 8 개를 할당 받음
		// (kmem_cache#21-o0...7)->ary[0]: NULL
		// (&(&mnt_id_ida)->idr)->id_free: kmem_cache#21-o7
		// (&(&mnt_id_ida)->idr)->id_free_cnt: 7
		//
		// struct ida_bitmap 의 메모리 kmem_cache#27-oX 할당 받음
		// (&mnt_id_ida)->free_bitmap: kmem_cache#27-oX
		//
		// (&(&mnt_id_ida)->idr)->id_free: NULL
		// (&(&mnt_id_ida)->idr)->id_free_cnt: 6
		// (&(&mnt_id_ida)->idr)->top: kmem_cache#21-o7 (struct idr_layer)
		// (&(&mnt_id_ida)->idr)->layers: 1
		// (&mnt_id_ida)->free_bitmap: NULL
		//
		// (kmem_cache#21-o7 (struct idr_layer))->ary[0]: NULL
		// (kmem_cache#21-o7 (struct idr_layer))->layer: 0
		// (kmem_cache#21-o7 (struct idr_layer))->ary[0]: kmem_cache#27-oX (struct ida_bitmap)
		// (kmem_cache#21-o7 (struct idr_layer))->count: 1
		//
		// (kmem_cache#27-oX (struct ida_bitmap))->bitmap 의 0 bit를 1로 set 수행
		//
		// (kmem_cache#2-oX (struct mount))->mnt_id: 0
		//
		// mnt_id_start: 1

		// err: 0
		if (err)
			goto out_free_cache;

		// name: "sysfs"
		if (name) {
			// mnt->mnt_devname: (kmem_cache#2-oX (struct mount))->mnt_devname, name: "sysfs", GFP_KERNEL: 0xD0
			// kstrdup("sysfs", GFP_KERNEL: 0xD0): kmem_cache#30-oX: "sysfs"
			mnt->mnt_devname = kstrdup(name, GFP_KERNEL);
			// mnt->mnt_devname: (kmem_cache#2-oX (struct mount))->mnt_devname: kmem_cache#30-oX: "sysfs"

			// mnt->mnt_devname: (kmem_cache#2-oX (struct mount))->mnt_devname: kmem_cache#30-oX: "sysfs"
			if (!mnt->mnt_devname)
				goto out_free_id;
		}

#ifdef CONFIG_SMP // CONFIG_SMP=y
		// mnt->mnt_pcp: (kmem_cache#2-oX (struct mount))->mnt_pcp, sizeof(struct mnt_pcp): 8 bytes
		// alloc_percpu(struct mnt_pcp): kmem_cache#26-o0 에서 할당된 8 bytes 메모리 주소
		mnt->mnt_pcp = alloc_percpu(struct mnt_pcp);
		// mnt->mnt_pcp: (kmem_cache#2-oX (struct mount))->mnt_pcp: kmem_cache#26-o0 에서 할당된 8 bytes 메모리 주소

		// mnt->mnt_pcp: (kmem_cache#2-oX (struct mount))->mnt_pcp: kmem_cache#26-o0 에서 할당된 8 bytes 메모리 주소
		if (!mnt->mnt_pcp)
			goto out_free_devname;

		// mnt->mnt_pcp->mnt_count: (kmem_cache#2-oX (struct mount))->mnt_pcp->mnt_count
		this_cpu_add(mnt->mnt_pcp->mnt_count, 1);
		// [pcp0] mnt->mnt_pcp->mnt_count: (kmem_cache#2-oX (struct mount))->mnt_pcp->mnt_count: 1
#else
		mnt->mnt_count = 1;
		mnt->mnt_writers = 0;
#endif

		// mnt->mnt_hash: (kmem_cache#2-oX (struct mount))->mnt_hash
		INIT_HLIST_NODE(&mnt->mnt_hash);

		// INIT_HLIST_NODE에서 한일:
		// ((kmem_cache#2-oX (struct mount))->mnt_hash)->next: NULL
		// ((kmem_cache#2-oX (struct mount))->mnt_hash)->pprev: NULL

		// mnt->mnt_child: (kmem_cache#2-oX (struct mount))->mnt_child
		INIT_LIST_HEAD(&mnt->mnt_child);

		// INIT_LIST_HEAD에서 한일:
		// ((kmem_cache#2-oX (struct mount))->mnt_child)->next: (kmem_cache#2-oX (struct mount))->mnt_child
		// ((kmem_cache#2-oX (struct mount))->mnt_child)->prev: (kmem_cache#2-oX (struct mount))->mnt_child

		// mnt->mnt_mounts: (kmem_cache#2-oX (struct mount))->mnt_mounts
		INIT_LIST_HEAD(&mnt->mnt_mounts);

		// INIT_LIST_HEAD에서 한일:
		// ((kmem_cache#2-oX (struct mount))->mnt_mounts)->next: (kmem_cache#2-oX (struct mount))->mnt_mounts
		// ((kmem_cache#2-oX (struct mount))->mnt_mounts)->prev: (kmem_cache#2-oX (struct mount))->mnt_mounts
		
		// mnt->mnt_list: (kmem_cache#2-oX (struct mount))->mnt_list
		INIT_LIST_HEAD(&mnt->mnt_list);

		// INIT_LIST_HEAD에서 한일:
		// ((kmem_cache#2-oX (struct mount))->mnt_list)->next: (kmem_cache#2-oX (struct mount))->mnt_list
		// ((kmem_cache#2-oX (struct mount))->mnt_list)->prev: (kmem_cache#2-oX (struct mount))->mnt_list

		// mnt->mnt_expire: (kmem_cache#2-oX (struct mount))->mnt_expire
		INIT_LIST_HEAD(&mnt->mnt_expire);

		// INIT_LIST_HEAD에서 한일:
		// ((kmem_cache#2-oX (struct mount))->mnt_expire)->next: (kmem_cache#2-oX (struct mount))->mnt_expire
		// ((kmem_cache#2-oX (struct mount))->mnt_expire)->prev: (kmem_cache#2-oX (struct mount))->mnt_expire

		// mnt->mnt_share: (kmem_cache#2-oX (struct mount))->mnt_share
		INIT_LIST_HEAD(&mnt->mnt_share);

		// INIT_LIST_HEAD에서 한일:
		// ((kmem_cache#2-oX (struct mount))->mnt_share)->next: (kmem_cache#2-oX (struct mount))->mnt_share
		// ((kmem_cache#2-oX (struct mount))->mnt_share)->prev: (kmem_cache#2-oX (struct mount))->mnt_share

		// mnt->mnt_slave_list: (kmem_cache#2-oX (struct mount))->mnt_slave_list
		INIT_LIST_HEAD(&mnt->mnt_slave_list);

		// INIT_LIST_HEAD에서 한일:
		// ((kmem_cache#2-oX (struct mount))->mnt_slave_list)->next: (kmem_cache#2-oX (struct mount))->mnt_slave_list
		// ((kmem_cache#2-oX (struct mount))->mnt_slave_list)->prev: (kmem_cache#2-oX (struct mount))->mnt_slave_list

		// mnt->mnt_slave: (kmem_cache#2-oX (struct mount))->mnt_slave
		INIT_LIST_HEAD(&mnt->mnt_slave);

		// INIT_LIST_HEAD에서 한일:
		// ((kmem_cache#2-oX (struct mount))->mnt_slave)->next: (kmem_cache#2-oX (struct mount))->mnt_slave
		// ((kmem_cache#2-oX (struct mount))->mnt_slave)->prev: (kmem_cache#2-oX (struct mount))->mnt_slave

#ifdef CONFIG_FSNOTIFY // CONFIG_FSNOTIFY=y
		// mnt->mnt_fsnotify_marks: (kmem_cache#2-oX (struct mount))->mnt_fsnotify_marks
		INIT_HLIST_HEAD(&mnt->mnt_fsnotify_marks);

		// INIT_HLIST_HEAD에서 한일:
		// ((kmem_cache#2-oX (struct mount))->mnt_fsnotify_marks)->first: NULL
#endif
	}

	// mnt: kmem_cache#2-oX (struct mount)
	return mnt;
	// return kmem_cache#2-oX (struct mount)

#ifdef CONFIG_SMP
out_free_devname:
	kfree(mnt->mnt_devname);
#endif
out_free_id:
	mnt_free_id(mnt);
out_free_cache:
	kmem_cache_free(mnt_cache, mnt);
	return NULL;
}

namespace.c::vfs_kern_mount()

  • call: start_kernel()
  • vfs_caches_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()
  • call: init_rootfs()

    • register_filesystem()
    • shmem_init()
  • call: shmem_init()

    • bdi_init()
    • shmem_init_inodecache()
    • register_filesystem()
    • kern_mount(): kern_mount_data(): shmem_fs_type
  • call: kern_mount_data()

    • vfs_kern_mount()
  • call: vfs_kern_mount()

    • alloc_vfsmnt()
    • mount_fs()
    • lock_mount_hash()
    • list_add_tail()
    • unlock_mount_hash()
// ARM10C 20160213
// type: &shmem_fs_type, MS_KERNMOUNT: 0x400000, type->name: (&shmem_fs_type)->name: "tmpfs", data: NULL
struct vfsmount *
vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)
{
	struct mount *mnt;
	struct dentry *root;

	// type: &sysfs_fs_type
	// type: &shmem_fs_type
	if (!type)
		return ERR_PTR(-ENODEV);

	// name: "sysfs", alloc_vfsmnt("sysfs"): kmem_cache#2-oX (struct mount)
	// name: "tmpfs", alloc_vfsmnt("tmpfs"):
	mnt = alloc_vfsmnt(name);
	// mnt: kmem_cache#2-oX (struct mount)

	// alloc_vfsmnt에서 한일:
	// struct mount의 메모리를 할당 받음 kmem_cache#2-oX (struct mount)
	//
	// idr_layer_cache를 사용하여 struct idr_layer 의 메모리 kmem_cache#21-o0...7를 8 개를 할당 받음
	// (kmem_cache#21-o0...7)->ary[0]: NULL
	// (&(&mnt_id_ida)->idr)->id_free: kmem_cache#21-o7
	// (&(&mnt_id_ida)->idr)->id_free_cnt: 7
	//
	// struct ida_bitmap 의 메모리 kmem_cache#27-oX 할당 받음
	// (&mnt_id_ida)->free_bitmap: kmem_cache#27-oX
	//
	// (&(&mnt_id_ida)->idr)->id_free: NULL
	// (&(&mnt_id_ida)->idr)->id_free_cnt: 6
	// (&(&mnt_id_ida)->idr)->top: kmem_cache#21-o7 (struct idr_layer)
	// (&(&mnt_id_ida)->idr)->layers: 1
	// (&mnt_id_ida)->free_bitmap: NULL
	//
	// (kmem_cache#21-o7 (struct idr_layer))->ary[0]: NULL
	// (kmem_cache#21-o7 (struct idr_layer))->layer: 0
	// (kmem_cache#21-o7 (struct idr_layer))->ary[0]: kmem_cache#27-oX (struct ida_bitmap)
	// (kmem_cache#21-o7 (struct idr_layer))->count: 1
	//
	// (kmem_cache#27-oX (struct ida_bitmap))->bitmap 의 0 bit를 1로 set 수행
	//
	// (kmem_cache#2-oX (struct mount))->mnt_id: 0
	//
	// mnt_id_start: 1
	//
	// (kmem_cache#2-oX (struct mount))->mnt_devname: kmem_cache#30-oX: "sysfs"
	// (kmem_cache#2-oX (struct mount))->mnt_pcp: kmem_cache#26-o0 에서 할당된 8 bytes 메모리 주소
	// [pcp0] (kmem_cache#2-oX (struct mount))->mnt_pcp->mnt_count: 1
	//
	// ((kmem_cache#2-oX (struct mount))->mnt_hash)->next: NULL
	// ((kmem_cache#2-oX (struct mount))->mnt_hash)->pprev: NULL
	// ((kmem_cache#2-oX (struct mount))->mnt_child)->next: (kmem_cache#2-oX (struct mount))->mnt_child
	// ((kmem_cache#2-oX (struct mount))->mnt_child)->prev: (kmem_cache#2-oX (struct mount))->mnt_child
	// ((kmem_cache#2-oX (struct mount))->mnt_mounts)->next: (kmem_cache#2-oX (struct mount))->mnt_mounts
	// ((kmem_cache#2-oX (struct mount))->mnt_mounts)->prev: (kmem_cache#2-oX (struct mount))->mnt_mounts
	// ((kmem_cache#2-oX (struct mount))->mnt_list)->next: (kmem_cache#2-oX (struct mount))->mnt_list
	// ((kmem_cache#2-oX (struct mount))->mnt_list)->prev: (kmem_cache#2-oX (struct mount))->mnt_list
	// ((kmem_cache#2-oX (struct mount))->mnt_expire)->next: (kmem_cache#2-oX (struct mount))->mnt_expire
	// ((kmem_cache#2-oX (struct mount))->mnt_expire)->prev: (kmem_cache#2-oX (struct mount))->mnt_expire
	// ((kmem_cache#2-oX (struct mount))->mnt_share)->next: (kmem_cache#2-oX (struct mount))->mnt_share
	// ((kmem_cache#2-oX (struct mount))->mnt_share)->prev: (kmem_cache#2-oX (struct mount))->mnt_share
	// ((kmem_cache#2-oX (struct mount))->mnt_slave_list)->next: (kmem_cache#2-oX (struct mount))->mnt_slave_list
	// ((kmem_cache#2-oX (struct mount))->mnt_slave_list)->prev: (kmem_cache#2-oX (struct mount))->mnt_slave_list
	// ((kmem_cache#2-oX (struct mount))->mnt_slave)->next: (kmem_cache#2-oX (struct mount))->mnt_slave
	// ((kmem_cache#2-oX (struct mount))->mnt_slave)->prev: (kmem_cache#2-oX (struct mount))->mnt_slave
	// ((kmem_cache#2-oX (struct mount))->mnt_fsnotify_marks)->first: NULL

	// mnt: kmem_cache#2-oX (struct mount)
	if (!mnt)
		return ERR_PTR(-ENOMEM);

// 2015/11/07 종료
// 2015/11/14 시작

	// flags: 0x400000, MS_KERNMOUNT: 0x400000
	if (flags & MS_KERNMOUNT)
		// mnt->mnt.mnt_flags: (kmem_cache#2-oX (struct mount))->mnt.mnt_flags, MNT_INTERNAL: 0x4000
		mnt->mnt.mnt_flags = MNT_INTERNAL;
		// mnt->mnt.mnt_flags: (kmem_cache#2-oX (struct mount))->mnt.mnt_flags: 0x4000

	// type: &sysfs_fs_type, flags: 0x400000, name: "sysfs", data: NULL
	// mount_fs(&sysfs_fs_type, 0x400000, "sysfs", NULL): kmem_cache#5-oX (struct dentry)
	root = mount_fs(type, flags, name, data);
	// root: kmem_cache#5-oX (struct dentry)

	// mount_fs에서 한일:
	//
	// struct sysfs_super_info의 메모리 kmem_cache#30-oX (struct sysfs_super_info)를 할당받음
	//
	// (kmem_cache#30-oX (struct sysfs_super_info))->ns[0]: NULL
	//
	// struct super_block 만큼의 메모리를 할당 받음 kmem_cache#25-oX (struct super_block)
	//
	// (&(&(&(&(kmem_cache#25-oX (struct super_block))->s_writers.counter[0...2])->lock)->wait_lock)->rlock)->raw_lock: { { 0 } }
	// (&(&(&(&(kmem_cache#25-oX (struct super_block))->s_writers.counter[0...2])->lock)->wait_lock)->rlock)->magic: 0xdead4ead
	// (&(&(&(&(kmem_cache#25-oX (struct super_block))->s_writers.counter[0...2])->lock)->wait_lock)->rlock)->owner: 0xffffffff
	// (&(&(&(&(kmem_cache#25-oX (struct super_block))->s_writers.counter[0...2])->lock)->wait_lock)->rlock)->owner_cpu: 0xffffffff
	// (&(&(kmem_cache#25-oX (struct super_block))->s_writers.counter[0...2])->list)->next: &(&(kmem_cache#25-oX (struct super_block))->s_writers.counter[0...2])->list
	// (&(&(kmem_cache#25-oX (struct super_block))->s_writers.counter[0...2])->list)->prev: &(&(kmem_cache#25-oX (struct super_block))->s_writers.counter[0...2])->list
	// (&(kmem_cache#25-oX (struct super_block))->s_writers.counter[0...2])->count: 0
	// (&(kmem_cache#25-oX (struct super_block))->s_writers.counter[0...2])->counters: kmem_cache#26-o0 에서 할당된 4 bytes 메모리 주소
	// list head 인 &percpu_counters에 &(&(kmem_cache#25-oX (struct super_block))->s_writers.counter[0...2])->list를 연결함
	//
	// &(&(kmem_cache#25-oX (struct super_block))->s_writers.wait)->lock을 사용한 spinlock 초기화
	// &(&(kmem_cache#25-oX (struct super_block))->s_writers.wait)->task_list를 사용한 list 초기화
	// &(&(kmem_cache#25-oX (struct super_block))->s_writers.wait_unfrozen)->lock을 사용한 spinlock 초기화
	// &(&(kmem_cache#25-oX (struct super_block))->s_writers.wait_unfrozen)->task_list를 사용한 list 초기화
	//
	// (&(kmem_cache#25-oX (struct super_block))->s_instances)->next: NULL
	// (&(kmem_cache#25-oX (struct super_block))->s_instances)->pprev: NULL
	// (&(kmem_cache#25-oX (struct super_block))->s_anon)->first: NULL
	//
	// (&(kmem_cache#25-oX (struct super_block))->s_inodes)->next: &(kmem_cache#25-oX (struct super_block))->s_inodes
	// (&(kmem_cache#25-oX (struct super_block))->s_inodes)->prev: &(kmem_cache#25-oX (struct super_block))->s_inodes
	//
	// (&(kmem_cache#25-oX (struct super_block))->s_dentry_lru)->node: kmem_cache#30-oX
	// (&(&(kmem_cache#25-oX (struct super_block))->s_dentry_lru)->active_nodes)->bits[0]: 0
	// ((&(kmem_cache#25-oX (struct super_block))->s_dentry_lru)->node[0].lock)->raw_lock: { { 0 } }
	// ((&(kmem_cache#25-oX (struct super_block))->s_dentry_lru)->node[0].lock)->magic: 0xdead4ead
	// ((&(kmem_cache#25-oX (struct super_block))->s_dentry_lru)->node[0].lock)->owner: 0xffffffff
	// ((&(kmem_cache#25-oX (struct super_block))->s_dentry_lru)->node[0].lock)->owner_cpu: 0xffffffff
	// ((&(kmem_cache#25-oX (struct super_block))->s_dentry_lru)->node[0].list)->next: (&(kmem_cache#25-oX (struct super_block))->s_dentry_lru)->node[0].list
	// ((&(kmem_cache#25-oX (struct super_block))->s_dentry_lru)->node[0].list)->prev: (&(kmem_cache#25-oX (struct super_block))->s_dentry_lru)->node[0].list
	// (&(kmem_cache#25-oX (struct super_block))->s_dentry_lru)->node[0].nr_items: 0
	// (&(kmem_cache#25-oX (struct super_block))->s_inode_lru)->node: kmem_cache#30-oX
	// (&(&(kmem_cache#25-oX (struct super_block))->s_inode_lru)->active_nodes)->bits[0]: 0
	// ((&(kmem_cache#25-oX (struct super_block))->s_inode_lru)->node[0].lock)->raw_lock: { { 0 } }
	// ((&(kmem_cache#25-oX (struct super_block))->s_inode_lru)->node[0].lock)->magic: 0xdead4ead
	// ((&(kmem_cache#25-oX (struct super_block))->s_inode_lru)->node[0].lock)->owner: 0xffffffff
	// ((&(kmem_cache#25-oX (struct super_block))->s_inode_lru)->node[0].lock)->owner_cpu: 0xffffffff
	// ((&(kmem_cache#25-oX (struct super_block))->s_inode_lru)->node[0].list)->next: (&(kmem_cache#25-oX (struct super_block))->s_inode_lru)->node[0].list
	// ((&(kmem_cache#25-oX (struct super_block))->s_inode_lru)->node[0].list)->prev: (&(kmem_cache#25-oX (struct super_block))->s_inode_lru)->node[0].list
	// (&(kmem_cache#25-oX (struct super_block))->s_inode_lru)->node[0].nr_items: 0
	//
	// (&(kmem_cache#25-oX (struct super_block))->s_mounts)->next: &(kmem_cache#25-oX (struct super_block))->s_mounts
	// (&(kmem_cache#25-oX (struct super_block))->s_mounts)->prev: &(kmem_cache#25-oX (struct super_block))->s_mounts
	//
	// (&(kmem_cache#25-oX (struct super_block))->s_umount)->activity: 0
	// &(&(kmem_cache#25-oX (struct super_block))->s_umount)->wait_lock을 사용한 spinlock 초기화
	// (&(&(kmem_cache#25-oX (struct super_block))->s_umount)->wait_list)->next: &(&(kmem_cache#25-oX (struct super_block))->s_umount)->wait_list
	// (&(&(kmem_cache#25-oX (struct super_block))->s_umount)->wait_list)->prev: &(&(kmem_cache#25-oX (struct super_block))->s_umount)->wait_list
	//
	// (&(kmem_cache#25-oX (struct super_block))->s_umount)->activity: -1
	//
	// (&(kmem_cache#25-oX (struct super_block))->s_vfs_rename_mutex)->count: 1
	// (&(kmem_cache#25-oX (struct super_block))->s_vfs_rename_mutex)->wait_lock)->rlock)->raw_lock: { { 0 } }
	// (&(kmem_cache#25-oX (struct super_block))->s_vfs_rename_mutex)->wait_lock)->rlock)->magic: 0xdead4ead
	// (&(kmem_cache#25-oX (struct super_block))->s_vfs_rename_mutex)->wait_lock)->rlock)->owner: 0xffffffff
	// (&(kmem_cache#25-oX (struct super_block))->s_vfs_rename_mutex)->wait_lock)->rlock)->owner_cpu: 0xffffffff
	// (&(&(kmem_cache#25-oX (struct super_block))->s_vfs_rename_mutex)->wait_list)->next: &(&(kmem_cache#25-oX (struct super_block))->s_vfs_rename_mutex)->wait_list
	// (&(&(kmem_cache#25-oX (struct super_block))->s_vfs_rename_mutex)->wait_list)->prev: &(&(kmem_cache#25-oX (struct super_block))->s_vfs_rename_mutex)->wait_list
	// (&(kmem_cache#25-oX (struct super_block))->s_vfs_rename_mutex)->onwer: NULL
	// (&(kmem_cache#25-oX (struct super_block))->s_vfs_rename_mutex)->magic: &(kmem_cache#25-oX (struct super_block))->s_vfs_rename_mutex
	// (&(kmem_cache#25-oX (struct super_block))->s_dquot.dqio_mutex)->count: 1
	// (&(kmem_cache#25-oX (struct super_block))->s_dquot.dqio_mutex)->wait_lock)->rlock)->raw_lock: { { 0 } }
	// (&(kmem_cache#25-oX (struct super_block))->s_dquot.dqio_mutex)->wait_lock)->rlock)->magic: 0xdead4ead
	// (&(kmem_cache#25-oX (struct super_block))->s_dquot.dqio_mutex)->wait_lock)->rlock)->owner: 0xffffffff
	// (&(kmem_cache#25-oX (struct super_block))->s_dquot.dqio_mutex)->wait_lock)->rlock)->owner_cpu: 0xffffffff
	// (&(&(kmem_cache#25-oX (struct super_block))->s_dquot.dqio_mutex)->wait_list)->next: &(&(kmem_cache#25-oX (struct super_block))->s_dquot.dqio_mutex)->wait_list
	// (&(&(kmem_cache#25-oX (struct super_block))->s_dquot.dqio_mutex)->wait_list)->prev: &(&(kmem_cache#25-oX (struct super_block))->s_dquot.dqio_mutex)->wait_list
	// (&(kmem_cache#25-oX (struct super_block))->s_dquot.dqio_mutex)->onwer: NULL
	// (&(kmem_cache#25-oX (struct super_block))->s_dquot.dqio_mutex)->magic: &(kmem_cache#25-oX (struct super_block))->s_dquot.dqio_mutex
	// (&(kmem_cache#25-oX (struct super_block))->s_dquot.dqonoff_mutex)->count: 1
	// (&(kmem_cache#25-oX (struct super_block))->s_dquot.dqonoff_mutex)->wait_lock)->rlock)->raw_lock: { { 0 } }
	// (&(kmem_cache#25-oX (struct super_block))->s_dquot.dqonoff_mutex)->wait_lock)->rlock)->magic: 0xdead4ead
	// (&(kmem_cache#25-oX (struct super_block))->s_dquot.dqonoff_mutex)->wait_lock)->rlock)->owner: 0xffffffff
	// (&(kmem_cache#25-oX (struct super_block))->s_dquot.dqonoff_mutex)->wait_lock)->rlock)->owner_cpu: 0xffffffff
	// (&(&(kmem_cache#25-oX (struct super_block))->s_dquot.dqonoff_mutex)->wait_list)->next: &(&(kmem_cache#25-oX (struct super_block))->s_dquot.dqonoff_mutex)->wait_list
	// (&(&(kmem_cache#25-oX (struct super_block))->s_dquot.dqonoff_mutex)->wait_list)->prev: &(&(kmem_cache#25-oX (struct super_block))->s_dquot.dqonoff_mutex)->wait_list
	// (&(kmem_cache#25-oX (struct super_block))->s_dquot.dqonoff_mutex)->onwer: NULL
	// (&(kmem_cache#25-oX (struct super_block))->s_dquot.dqonoff_mutex)->magic: &(kmem_cache#25-oX (struct super_block))->s_dquot.dqonoff_mutex
	// (&(kmem_cache#25-oX (struct super_block))->s_dquot.dqptr_sem)->activity: 0
	// &(&(kmem_cache#25-oX (struct super_block))->s_dquot.dqptr_sem)->wait_lock을 사용한 spinlock 초기화
	// (&(&(kmem_cache#25-oX (struct super_block))->s_dquot.dqptr_sem)->wait_list)->next: &(&(kmem_cache#25-oX (struct super_block))->s_dquot.dqptr_sem)->wait_list
	// (&(&(kmem_cache#25-oX (struct super_block))->s_dquot.dqptr_sem)->wait_list)->prev: &(&(kmem_cache#25-oX (struct super_block))->s_dquot.dqptr_sem)->wait_list
	//
	// (kmem_cache#25-oX (struct super_block))->s_flags: 0x400000
	// (kmem_cache#25-oX (struct super_block))->s_bdi: &default_backing_dev_info
	// (kmem_cache#25-oX (struct super_block))->s_count: 1
	// ((kmem_cache#25-oX (struct super_block))->s_active)->counter: 1
	// (kmem_cache#25-oX (struct super_block))->s_maxbytes: 0x7fffffff
	// (kmem_cache#25-oX (struct super_block))->s_op: &default_op
	// (kmem_cache#25-oX (struct super_block))->s_time_gran: 1000000000
	// (kmem_cache#25-oX (struct super_block))->cleancache_poolid: -1
	// (kmem_cache#25-oX (struct super_block))->s_shrink.seeks: 2
	// (kmem_cache#25-oX (struct super_block))->s_shrink.scan_objects: super_cache_scan
	// (kmem_cache#25-oX (struct super_block))->s_shrink.count_objects: super_cache_count
	// (kmem_cache#25-oX (struct super_block))->s_shrink.batch: 1024
	// (kmem_cache#25-oX (struct super_block))->s_shrink.flags: 1
	//
	// idr_layer_cache를 사용하여 struct idr_layer 의 메모리 kmem_cache#21-o0...7를 8 개를 할당 받음
	// (kmem_cache#21-o0...7)->ary[0]: NULL
	// (&(&unnamed_dev_ida)->idr)->id_free: kmem_cache#21-o7
	// (&(&unnamed_dev_ida)->idr)->id_free_cnt: 7
	//
	// struct ida_bitmap 의 메모리 kmem_cache#27-oX 할당 받음
	// (&unnamed_dev_ida)->free_bitmap: kmem_cache#27-oX
	//
	// (&(&unnamed_dev_ida)->idr)->id_free: NULL
	// (&(&unnamed_dev_ida)->idr)->id_free_cnt: 6
	// (&(&unnamed_dev_ida)->idr)->top: kmem_cache#21-o7 (struct idr_layer)
	// (&(&unnamed_dev_ida)->idr)->layers: 1
	// (&unnamed_dev_ida)->free_bitmap: NULL
	//
	// (kmem_cache#21-o7 (struct idr_layer))->ary[0]: NULL
	// (kmem_cache#21-o7 (struct idr_layer))->layer: 0
	// (kmem_cache#21-o7 (struct idr_layer))->ary[0]: kmem_cache#27-oX (struct ida_bitmap)
	// (kmem_cache#21-o7 (struct idr_layer))->count: 1
	//
	// (kmem_cache#27-oX (struct ida_bitmap))->bitmap 의 0 bit를 1로 set 수행
	//
	// unnamed_dev_start: 1
	//
	// (kmem_cache#25-oX (struct super_block))->s_dev: 0
	// (kmem_cache#25-oX (struct super_block))->s_bdi: &noop_backing_dev_info
	// (kmem_cache#25-oX (struct super_block))->s_fs_info: kmem_cache#30-oX (struct sysfs_super_info)
	//
	// (kmem_cache#25-oX (struct super_block))->s_type: &sysfs_fs_type
	// (kmem_cache#25-oX (struct super_block))->s_id: "sysfs"
	//
	// list head인 &super_blocks 에 (kmem_cache#25-oX (struct super_block))->s_list을 tail에 추가
	// (&(kmem_cache#25-oX (struct super_block))->s_instances)->next: NULL
	// (&(&sysfs_fs_type)->fs_supers)->first: &(kmem_cache#25-oX (struct super_block))->s_instances
	// (&(kmem_cache#25-oX (struct super_block))->s_instances)->pprev: &(&(&sysfs_fs_type)->fs_supers)->first
	//
	// (&(kmem_cache#25-oX (struct super_block))->s_shrink)->flags: 0
	// (&(kmem_cache#25-oX (struct super_block))->s_shrink)->nr_deferred: kmem_cache#30-oX
	// head list인 &shrinker_list에 &(&(kmem_cache#25-oX (struct super_block))->s_shrink)->list를 tail로 추가함
	//
	// (kmem_cache#25-oX (struct super_block))->s_blocksize: 0x1000
	// (kmem_cache#25-oX (struct super_block))->s_blocksize_bits: 12
	// (kmem_cache#25-oX (struct super_block))->s_magic: 0x62656572
	// (kmem_cache#25-oX (struct super_block))->s_op: &sysfs_ops
	// (kmem_cache#25-oX (struct super_block))->s_time_gran: 1
	//
	// inode용 kmem_cache인 inode_cachep: kmem_cache#4 를 사용하여 inode를 위한 메모리 kmem_cache#4-oX (struct inode) 할당 받음
	//
	// (kmem_cache#4-oX (struct inode))->i_sb: kmem_cache#25-oX (struct super_block)
	// (kmem_cache#4-oX (struct inode))->i_blkbits: 12
	// (kmem_cache#4-oX (struct inode))->i_flags: 0
	// (kmem_cache#4-oX (struct inode))->i_count: 1
	// (kmem_cache#4-oX (struct inode))->i_op: &empty_iops
	// (kmem_cache#4-oX (struct inode))->__i_nlink: 1
	// (kmem_cache#4-oX (struct inode))->i_opflags: 0
	// (kmem_cache#4-oX (struct inode))->i_uid: 0
	// (kmem_cache#4-oX (struct inode))->i_gid: 0
	// (kmem_cache#4-oX (struct inode))->i_count: 0
	// (kmem_cache#4-oX (struct inode))->i_size: 0
	// (kmem_cache#4-oX (struct inode))->i_blocks: 0
	// (kmem_cache#4-oX (struct inode))->i_bytes: 0
	// (kmem_cache#4-oX (struct inode))->i_generation: 0
	// (kmem_cache#4-oX (struct inode))->i_pipe: NULL
	// (kmem_cache#4-oX (struct inode))->i_bdev: NULL
	// (kmem_cache#4-oX (struct inode))->i_cdev: NULL
	// (kmem_cache#4-oX (struct inode))->i_rdev: 0
	// (kmem_cache#4-oX (struct inode))->dirtied_when: 0
	//
	// &(kmem_cache#4-oX (struct inode))->i_lock을 이용한 spin lock 초기화 수행
	//
	// ((&(kmem_cache#4-oX (struct inode))->i_lock)->rlock)->raw_lock: { { 0 } }
	// ((&(kmem_cache#4-oX (struct inode))->i_lock)->rlock)->magic: 0xdead4ead
	// ((&(kmem_cache#4-oX (struct inode))->i_lock)->rlock)->owner: 0xffffffff
	// ((&(kmem_cache#4-oX (struct inode))->i_lock)->rlock)->owner_cpu: 0xffffffff
	//
	// (&(kmem_cache#4-oX (struct inode))->i_mutex)->count: 1
	// (&(&(&(kmem_cache#4-oX (struct inode))->i_mutex)->wait_lock)->rlock)->raw_lock: { { 0 } }
	// (&(&(&(kmem_cache#4-oX (struct inode))->i_mutex)->wait_lock)->rlock)->magic: 0xdead4ead
	// (&(&(&(kmem_cache#4-oX (struct inode))->i_mutex)->wait_lock)->rlock)->owner: 0xffffffff
	// (&(&(&(kmem_cache#4-oX (struct inode))->i_mutex)->wait_lock)->rlock)->owner_cpu: 0xffffffff
	// (&(&(kmem_cache#4-oX (struct inode))->i_mutex)->wait_list)->next: &(&(kmem_cache#4-oX (struct inode))->i_mutex)->wait_list
	// (&(&(kmem_cache#4-oX (struct inode))->i_mutex)->wait_list)->prev: &(&(kmem_cache#4-oX (struct inode))->i_mutex)->wait_list
	// (&(kmem_cache#4-oX (struct inode))->i_mutex)->onwer: NULL
	// (&(kmem_cache#4-oX (struct inode))->i_mutex)->magic: &(kmem_cache#4-oX (struct inode))->i_mutex
	//
	// (kmem_cache#4-oX (struct inode))->i_dio_count: 0
	//
	// (&(kmem_cache#4-oX (struct inode))->i_data)->a_ops: &empty_aops
	// (&(kmem_cache#4-oX (struct inode))->i_data)->host: kmem_cache#4-oX (struct inode)
	// (&(kmem_cache#4-oX (struct inode))->i_data)->flags: 0
	// (&(kmem_cache#4-oX (struct inode))->i_data)->flags: 0x200DA
	// (&(kmem_cache#4-oX (struct inode))->i_data)->private_data: NULL
	// (&(kmem_cache#4-oX (struct inode))->i_data)->backing_dev_info: &default_backing_dev_info
	// (&(kmem_cache#4-oX (struct inode))->i_data)->writeback_index: 0
	//
	// (kmem_cache#4-oX (struct inode))->i_private: NULL
	// (kmem_cache#4-oX (struct inode))->i_mapping: &(kmem_cache#4-oX (struct inode))->i_data
	// (&(kmem_cache#4-oX (struct inode))->i_dentry)->first: NULL
	// (kmem_cache#4-oX (struct inode))->i_acl: (void *)(0xFFFFFFFF),
	// (kmem_cache#4-oX (struct inode))->i_default_acl: (void *)(0xFFFFFFFF)
	// (kmem_cache#4-oX (struct inode))->i_fsnotify_mask: 0
	//
	// [pcp0] nr_inodes: 1
	//
	// (kmem_cache#4-oX (struct inode))->i_ino: 1
	// (kmem_cache#4-oX (struct inode))->i_state: 0x8
	//
	// (&(kmem_cache#4-oX (struct inode))->i_hash)->next: NULL
	// (256KB의 메모리 공간 + 계산된 hash index 값)->first: &(kmem_cache#4-oX (struct inode))->i_hash
	// (&(kmem_cache#4-oX (struct inode))->i_hash)->pprev: &(&(kmem_cache#4-oX (struct inode))->i_hash)
	//
	// head list인 &(kmem_cache#4-oX (struct inode))->i_sb->s_inodes에 &(kmem_cache#4-oX (struct inode))->i_sb_list를 추가함
	//
	// (&sysfs_root)->s_count: 2
	//
	// (kmem_cache#4-oX (struct inode))->i_private: 2
	// (kmem_cache#4-oX (struct inode))->i_mapping->a_ops: &sysfs_aops
	// (kmem_cache#4-oX (struct inode))->i_mapping->backing_dev_info: &sysfs_backing_dev_info
	// (kmem_cache#4-oX (struct inode))->i_op: &sysfs_inode_operations
	// (kmem_cache#4-oX (struct inode))->i_atime: 현재시간값,
	// (kmem_cache#4-oX (struct inode))->i_mtime: 현재시간값,
	// (kmem_cache#4-oX (struct inode))->i_ctime: 현재시간값
	// (kmem_cache#4-oX (struct inode))->i_mode: 40447
	// (kmem_cache#4-oX (struct inode))->__i_nlink: 2
	// (kmem_cache#4-oX (struct inode))->i_op: &sysfs_dir_inode_operations
	// (kmem_cache#4-oX (struct inode))->i_fop: &sysfs_dir_operations
	// (kmem_cache#4-oX (struct inode))->i_state: 0x0
	// memory barrier 수행 (공유자원을 다른 cpu core가 사용할 수 있게 해줌)
	//
	// dentry_cache인 kmem_cache#5을 사용하여 dentry로 사용할 메모리 kmem_cache#5-oX (struct dentry)을 할당받음
	//
	// (kmem_cache#5-oX (struct dentry))->d_iname[35]: 0
	// (kmem_cache#5-oX (struct dentry))->d_name.len: 1
	// (kmem_cache#5-oX (struct dentry))->d_name.hash: (&name)->hash: 0
	// (kmem_cache#5-oX (struct dentry))->d_iname: "/"
	//
	// 공유자원을 다른 cpu core가 사용할수 있게 함
	//
	// (kmem_cache#5-oX (struct dentry))->d_name.name: "/"
	// (kmem_cache#5-oX (struct dentry))->d_lockref.count: 1
	// (kmem_cache#5-oX (struct dentry))->d_flags: 0
	//
	// (&(kmem_cache#5-oX (struct dentry))->d_lock)->raw_lock: { { 0 } }
	// (&(kmem_cache#5-oX (struct dentry))->d_lock)->magic: 0xdead4ead
	// (&(kmem_cache#5-oX (struct dentry))->d_lock)->owner: 0xffffffff
	// (&(kmem_cache#5-oX (struct dentry))->d_lock)->owner_cpu: 0xffffffff
	//
	// (&(kmem_cache#5-oX (struct dentry))->d_seq)->sequence: 0
	//
	// (kmem_cache#5-oX (struct dentry))->d_inode: NULL
	//
	// (kmem_cache#5-oX (struct dentry))->d_parent: kmem_cache#5-oX (struct dentry)
	// (kmem_cache#5-oX (struct dentry))->d_sb: kmem_cache#25-oX (struct super_block)
	// (kmem_cache#5-oX (struct dentry))->d_op: NULL
	// (kmem_cache#5-oX (struct dentry))->d_fsdata: NULL
	//
	// (&(kmem_cache#5-oX (struct dentry))->d_hash)->next: NULL
	// (&(kmem_cache#5-oX (struct dentry))->d_hash)->pprev: NULL
	// (&(kmem_cache#5-oX (struct dentry))->d_lru)->next: &(kmem_cache#5-oX (struct dentry))->d_lru
	// (&(kmem_cache#5-oX (struct dentry))->d_lru)->prev: &(kmem_cache#5-oX (struct dentry))->d_lru
	// (&(kmem_cache#5-oX (struct dentry))->d_subdirs)->next: &(kmem_cache#5-oX (struct dentry))->d_subdirs
	// (&(kmem_cache#5-oX (struct dentry))->d_subdirs)->prev: &(kmem_cache#5-oX (struct dentry))->d_subdirs
	// (&(kmem_cache#5-oX (struct dentry))->d_alias)->next: NULL
	// (&(kmem_cache#5-oX (struct dentry))->d_alias)->pprev: NULL
	// (&(kmem_cache#5-oX (struct dentry))->d_u.d_child)->next: &(kmem_cache#5-oX (struct dentry))->d_u.d_child
	// (&(kmem_cache#5-oX (struct dentry))->d_u.d_child)->prev: &(kmem_cache#5-oX (struct dentry))->d_u.d_child
	//
	// (kmem_cache#5-oX (struct dentry))->d_op: NULL
	//
	// [pcp0] nr_dentry: 1
	//
	// (&(kmem_cache#5-oX (struct dentry))->d_alias)->next: NULL
	// (&(kmem_cache#4-oX (struct inode))->i_dentry)->first: &(kmem_cache#5-oX (struct dentry))->d_alias
	// (&(kmem_cache#5-oX (struct dentry))->d_alias)->pprev: &(&(kmem_cache#5-oX (struct dentry))->d_alias)
	//
	// (kmem_cache#5-oX (struct dentry))->d_inode: kmem_cache#4-oX (struct inode)
	//
	// 공유자원을 다른 cpu core가 사용할수 있게 함
	// (&(kmem_cache#5-oX (struct dentry))->d_seq)->sequence: 2
	//
	// (kmem_cache#5-oX (struct dentry))->d_flags: 0x00100000
	//
	// (kmem_cache#5-oX (struct dentry))->d_fsdata: &sysfs_root
	// (kmem_cache#25-oX (struct super_block))->s_root: kmem_cache#5-oX (struct dentry)
	// (kmem_cache#25-oX (struct super_block))->s_d_op: &sysfs_dentry_ops
	//
	// (kmem_cache#25-oX (struct super_block))->s_flags: 0x40400000
	//
	// (&(kmem_cache#5-oX (struct dentry))->d_lockref)->count: 1
	//
	// sb->s_flags: (kmem_cache#25-oX (struct super_block))->s_flags: 0x60400000
	//
	// (&(kmem_cache#25-oX (struct super_block))->s_umount)->activity: 0

	// root: kmem_cache#5-oX (struct dentry), IS_ERR(kmem_cache#5-oX (struct dentry)): 0
	if (IS_ERR(root)) {
		free_vfsmnt(mnt);
		return ERR_CAST(root);
	}

	// mnt->mnt.mnt_root: (kmem_cache#2-oX (struct mount))->mnt.mnt_root, root: kmem_cache#5-oX (struct dentry)
	mnt->mnt.mnt_root = root;
	// mnt->mnt.mnt_root: (kmem_cache#2-oX (struct mount))->mnt.mnt_root: kmem_cache#5-oX (struct dentry)

	// mnt->mnt.mnt_sb: (kmem_cache#2-oX (struct mount))->mnt.mnt_sb,
	// root->d_sb: (kmem_cache#5-oX (struct dentry))->d_sb: kmem_cache#25-oX (struct super_block)
	mnt->mnt.mnt_sb = root->d_sb;
	// mnt->mnt.mnt_sb: (kmem_cache#2-oX (struct mount))->mnt.mnt_sb: kmem_cache#25-oX (struct super_block)

	// mnt->mnt_mountpoint: (kmem_cache#2-oX (struct mount))->mnt_mountpoint,
	// mnt->mnt.mnt_root: (kmem_cache#2-oX (struct mount))->mnt.mnt_root: kmem_cache#5-oX (struct dentry)
	mnt->mnt_mountpoint = mnt->mnt.mnt_root;
	// mnt->mnt_mountpoint: (kmem_cache#2-oX (struct mount))->mnt_mountpoint: kmem_cache#5-oX (struct dentry)

	// mnt->mnt_parent: (kmem_cache#2-oX (struct mount))->mnt_parent, mnt: kmem_cache#2-oX (struct mount)
	mnt->mnt_parent = mnt;
	// mnt->mnt_parent: (kmem_cache#2-oX (struct mount))->mnt_parent: kmem_cache#2-oX (struct mount)

// 2015/12/19 종료
// 2016/01/09 시작

	lock_mount_hash();

	// lock_mount_hash에서 한일:
	// &(&mount_lock)->lock 을 사용하여 spin lock 수행
	// (&(&mount_lock)->seqcount)->sequence: 1
	// 공유자원을 다른 cpu core가 사용할수 있게 메모리 적용

	// &mnt->mnt_instance: &(kmem_cache#2-oX (struct mount))->mnt_instance,
	// root->d_sb: (kmem_cache#5-oX (struct dentry))->d_sb: kmem_cache#25-oX (struct super_block),
	// &root->d_sb->s_mounts: &(kmem_cache#5-oX (struct dentry))->d_sb->s_mounts
	list_add_tail(&mnt->mnt_instance, &root->d_sb->s_mounts);

	// list_add_tail에서 한일:
	// list head인 &(kmem_cache#5-oX (struct dentry))->d_sb->s_mounts에
	// &(kmem_cache#2-oX (struct mount))->mnt_instance를 tail로 연결

	unlock_mount_hash();

	// unlock_mount_hash에서 한일:
	// 공유자원을 다른 cpu core가 사용할수 있게 메모리 적용
	// (&(&mount_lock)->seqcount)->sequence: 2
	// &(&mount_lock)->lock을 사용하여 spin unlock 수행

	// &mnt->mnt: &(kmem_cache#2-oX (struct mount))->mnt
	return &mnt->mnt;
	// return &(kmem_cache#2-oX (struct mount))->mnt
}
EXPORT_SYMBOL_GPL(vfs_kern_mount);

log

e6fa45e..f9802ee  master     -> origin/master
Updating e6fa45e..f9802ee
Fast-forward
Reference/Breakdown/002_linux-kernel_20130504.md |   2 +-
Reference/Breakdown/Figures/002_slab.png         | Bin 0 -> 19636 bytes
fs/namespace.c                                   | 277 +++++++++++++++++++++++++++++++++++++++++++----------------------
fs/super.c                                       | 141 ++++++++++++++++++++++-----------
fs/sysfs/dir.c                                   |  19 +++--
fs/sysfs/mount.c                                 | 147 +++++++++++++++++++++++------------
include/linux/memcontrol.h                       |   1 +
include/linux/mm.h                               |  12 +++
include/linux/mm_types.h                         |   1 +
include/linux/slab.h                             |   2 +
include/linux/spinlock.h                         |   4 +
include/trace/events/kmem.h                      |   1 +
lib/idr.c                                        | 516 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------
mm/slab.h                                        |  10 +++
mm/slub.c                                        |  19 ++++-
15 files changed, 899 insertions(+), 253 deletions(-)
create mode 100644 Reference/Breakdown/Figures/002_slab.png
f9802ee..89401fa  master     -> origin/master
Updating f9802ee..89401fa
Fast-forward
Reference/Breakdown/002_linux-kernel_20130504.md | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
89401fa..93cdf0a  master     -> origin/master
Updating 89401fa..93cdf0a
Fast-forward
arch/arm/include/asm/bitops.h |   2 +-
fs/namespace.c                |   8 +++---
fs/sysfs/dir.c                |  40 +++++++++++++++++++++++++----
fs/sysfs/mount.c              |   4 +--
lib/idr.c                     | 197 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
5 files changed, 228 insertions(+), 23 deletions(-)