============
-
132 주차 진도를 복습하였습니다.
-
mnt_alloc_id()
- start_kernel 1 ~/init/main.c
- vfs_caches_init 925 ~/init/main.c
- mnt_init 3807 ~/linux-stable/fs/dcache.c
- init_rootfs 4028 init_rootfs();
- shmem_init 639 ~/init/do_mounts.c
- kern_mount 2937 ~/linux-stable/mm/shmem.c
- kern_mount_data 1968 ~/include/linux/fs.h
- vfs_kern_mount 4053 mnt = vfs_kern_mount(type, MS_KERNMOUNT, type->name, data);
- alloc_vfsmnt 1088 mnt = alloc_vfsmnt(name);
- mnt_alloc_id 340 err = mnt_alloc_id(mnt);
- 131주차 함수 호출 구조
- 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()
- 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);
- 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();
-
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();
-
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();
-
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);
-
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)
-
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);
-
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);
-
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);
-
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
}
-
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);
-
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
}
- 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);
6ca1b58..25e921c master -> origin/master
Updating 6ca1b58..25e921c
Fast-forward
fs/namespace.c | 17 ++++--
lib/idr.c | 168 ++++++++++++++++++++++++++++++++++-----------------------
2 files changed, 115 insertions(+), 70 deletions(-)