============
- ᇂ154차 시작 위치
- start_kernel 1 ~/init/main.c
- cgroup_init 941 ~/init/main.c
- kobject_create_and_add 6202 ~/kernel/cgroup.c
- kobject_add 1269 ~/lib/kobject.c
- kobject_add_varg 777 ~/lib/kobject.c
- kobject_add_internal 640 ~/lib/kobject.c
- create_dir 363 ~/lib/kobject.c
- sysfs_create_dir_ns 101 ~/lib/kobject.c
- create_dir 1351 // create_dir(kmem_cache#30-oX (struct kobject) (cgroup), kmem_cache#1-oX (struct sysfs_dirent) (fs), 0, "cgroup", NULL, &sd): 0
- sysfs_addrm_start 1203 sysfs_addrm_start(&acxt);
- call: start_kernel()
- lockdep_init()
- smp_setup_processor_id()
- debug_objects_early_init()
- boot_init_stack_canary()
- cgroup_init_early()
- local_irq_disable()
- boot_cpu_init()
- page_address_init()
- pr_notice()
- setup_arch()
- mm_init_owner()
- mm_init_cpumask()
- setup_command_line
- build_all_zonelists()
- page_alloc_init()
- pr_notice()
- parse_early_param()
- parse_args()
- jump_label_init()
- setup_log_buf()
- pidhash_init()
- vfs_caches_init_early()
- sort_main_extable()
- trap_init()
- mm_init()
- sched_init()
- preempt_disable()
- irqs_disabled()
- local_irq_disabled()
- idr_init_cache()
- rcu_init()
- tick_nohz_init()
- contect_tracking_init()
- radix_tree_init()
- early_irq_init()
- init_IRQ()
- tick_init()
- init_timers()
- hrtimers_init()
- softirq_init()
- timekeeping_init()
- time_init()
- sched_clock_postinit()
- pref_event_init()
- profile_init()
- call_function_init()
- irqs_disabled()
- local_irq_enabled()
- kmem_cache_init_late()
- console_init()
- lockdep_init()
- lockdep_info()
- locking_selftest()
- virt_to_page()
- page_to_pfn()
- page_cgroup_init()
- debug_objects_mem_init()
- kmemleak_init()
- setup_per_cpu_pageset()
- numa_policy_init()
- sched_clock_init()
- calibrate_delay()
- pidmap_init()
- anon_vma_init()
- thread_info_cache_init()
- cred_init()
- fork_init()
- proc_caches_init()
- buffer_init()
- key_init()
- security_init()
- dbg_late_init()
- vfs_caches_init()
- signals_init()
- page_writeback_init()
- proc_root_init()
- cgroup_init()
- call: cgroup_init()
- bdi_init()
- for_each_buildtin_subsys()
- cgroup_init_subsys(ss): ss=cgroup_subsys
- mutex_lock(&cgroup_mutex)
- mutex_lock(&cgroup_root_mutex)
- key = css_set_hash(init_css_set.subsys)
- hash_add(css_set_table, &init_css_set.hlist, key)
- BUG_ON(cgroup_init_root_id(&cgroup_dummy_root, 0, 1))
- err = idr_alloc(&cgroup_dummy_root.cgroup_idr, cgroup_dummy_top, 0, 1, GFP_KERNEL);
- BUG_ON(err < 0);
- mutex_unlock(&cgroup_root_mutex);
- mutex_unlock(&cgroup_mutex);
- kobject_create_and_add("cgroup", fs_kobj)
- call: kobject_create_and_add("cgroup", fs_kobj);
- kobj = kobject_create();
- retval = kobject_add(kobj, parent, "%s", name);
- call: kobject_add()
- va_start(args, fmt);
- retval = kobject_add_varg(kobj, parent, fmt, args);
- call: start_kernel()
- lockdep_init()
- smp_setup_processor_id()
- debug_objects_early_init()
- boot_init_stack_canary()
- cgroup_init_early()
- local_irq_disable()
- boot_cpu_init()
- page_address_init()
- pr_notice()
- setup_arch()
- mm_init_owner()
- mm_init_cpumask()
- setup_command_line
- build_all_zonelists()
- page_alloc_init()
- pr_notice()
- parse_early_param()
- parse_args()
- jump_label_init()
- setup_log_buf()
- pidhash_init()
- vfs_caches_init_early()
- sort_main_extable()
- trap_init()
- mm_init()
- sched_init()
- preempt_disable()
- irqs_disabled()
- local_irq_disabled()
- idr_init_cache()
- rcu_init()
- tick_nohz_init()
- contect_tracking_init()
- radix_tree_init()
- early_irq_init()
- init_IRQ()
- tick_init()
- init_timers()
- hrtimers_init()
- softirq_init()
- timekeeping_init()
- time_init()
- sched_clock_postinit()
- pref_event_init()
- profile_init()
- call_function_init()
- irqs_disabled()
- local_irq_enabled()
- kmem_cache_init_late()
- console_init()
- lockdep_init()
- lockdep_info()
- locking_selftest()
- virt_to_page()
- page_to_pfn()
- page_cgroup_init()
- debug_objects_mem_init()
- kmemleak_init()
- setup_per_cpu_pageset()
- numa_policy_init()
- sched_clock_init()
- calibrate_delay()
- pidmap_init()
- anon_vma_init()
- thread_info_cache_init()
- cred_init()
- fork_init()
- proc_caches_init()
- buffer_init()
- key_init()
- security_init()
- dbg_late_init()
- vfs_caches_init()
- signals_init()
- page_writeback_init()
- proc_root_init()
// ARM10C 20130824
asmlinkage void __init start_kernel(void)
{
char * command_line;
extern const struct kernel_param __start___param[], __stop___param[];
// ATAG,DTB 정보로 사용
/*
* Need to run as early as possible, to initialize the
* lockdep hash:
*/
lockdep_init();
smp_setup_processor_id();
debug_objects_early_init();
/*
* Set up the the initial canary ASAP:
*/
boot_init_stack_canary();
cgroup_init_early();
// cgroup 를 사용하기 위한 cgroup_dummy_root, cgroup_subsys 의 구조체 초기화 수행
local_irq_disable();
// IRQ를 disable 함
early_boot_irqs_disabled = true;
// early_boot_irqs_disabled: true
/*
* Interrupts are still disabled. Do necessary setups, then
* enable them
*/
boot_cpu_init();
// 현재 cpu(core id)를 얻어서 cpu_XXX_bits[] 의 cpu를 셋한다.
page_address_init();
// 128개의 page_address_htable 배열을 초기화
pr_notice("%s", linux_banner);
// 배너:
// Linux version 2.6.37_DM385_IPNC_3.50.00
// (a0875405@bangvideoapps01) (gcc version 4.5.3 20110311
// (prerelease) (GCC) ) #1 Fri Dec 21 17:27:08 IST 2012
setup_arch(&command_line);
mm_init_owner(&init_mm, &init_task); // null function
mm_init_cpumask(&init_mm); // null function
// command_line: exynos5420-smdk5420.dts 파일의 chosen node 의 bootarg 값
// "console=ttySAC2,115200 init=/linuxrc"
setup_command_line(command_line);
// saved_command_line 및 static_command_line 할당
setup_nr_cpu_ids();
setup_per_cpu_areas();
// pcpu 구조체를 만들어 줌 (mm/percpu.c)
smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */
// boot cpu 0의 pcpu 영역의 base주소를 core register에 설정해줌
build_all_zonelists(NULL, NULL);
page_alloc_init();
// cpu_chain에 page_alloc_cpu_notify를 연결함 (mutex lock/unlock 사용)
// boot_command_line: "console=ttySAC2,115200 init=/linuxrc"
pr_notice("Kernel command line: %s\n", boot_command_line);
// "Kernel command line: console=ttySAC2,115200 init=/linuxrc"
parse_early_param();
// setup_arch에서 수행했던 작업 다시 수행
// command arg에서 각 요소들을 파싱하여 early init section으로 설정된 디바이스 초기화.
// 우리는 serial device가 검색이 되지만 config설정은 없어서 아무것도 안함.
// static_command_line: "console=ttySAC2,115200 init=/linuxrc"
parse_args("Booting kernel", static_command_line, __start___param,
__stop___param - __start___param,
-1, -1, &unknown_bootoption);
// DTB에서 넘어온 bootargs를 파싱하여 param, val을 뽑아내고 그에 대응되는
// kernel_param 구조체에 값을 등록함.
jump_label_init();
// HAVE_JUMP_LABEL 이 undefined 이므로 NULL 함수
/*
* These use large bootmem allocations and must precede
* kmem_cache_init()
*/
setup_log_buf(0);
// defalut log_buf의 크기는 __LOG_BUF_LEN: 0x20000 (128KB) 임
// early_param 에서 호출했던 log_buf_len 값이 있다면 log_buf의 크기를 넘어온 크기로 만듬
pidhash_init();
// pidhash의 크기를 16kB만큼 할당 받고 4096개의 hash list를 만듬
vfs_caches_init_early();
// Dentry cache, Inode-cache용 hash를 위한 메모리 공간을 각각 512kB, 256kB만큼 할당 받고,
// 131072, 65536개 만큼 hash table을 각각 만듬
sort_main_extable();
// extable 을 cmp_ex를 이용하여 sort수행
trap_init(); // null function
mm_init();
// buddy와 slab 을 활성화 하고 기존 할당 받은 bootmem 은 buddy,
// pcpu 메모리, vmlist 는 slab으로 이관
/*
* Set up the scheduler prior starting any interrupts (such as the
* timer interrupt). Full topology setup happens at smp_init()
* time - but meanwhile we still have a functioning scheduler.
*/
sched_init();
// scheduler가 사용하는 자료 구조 초기화, idle_threads를 init_task로 세팅
/*
* Disable preemption - early bootup scheduling is extremely
* fragile until we cpu_idle() for the first time.
*/
preempt_disable();
// preempt count를 증가시켜 preemption 못하도록 막음
// irqs_disabled(): 1
if (WARN(!irqs_disabled(), "Interrupts were enabled *very* early, fixing it\n"))
local_irq_disable();
idr_init_cache();
// integer ID management로 사용하는 idr_layer_cache에 kmem_cache#21 을 생성 및 초기화 후 할당
rcu_init();
// rcu 자료구조 bh, sched, preempt 를 각각 초기화 수행함
tick_nohz_init(); // null function
context_tracking_init(); // null function
radix_tree_init();
// radix tree로 사용하는 radix_tree_node_cachep에 kmem_cache#20을 생성 및 초기화 후 할당하고
// height_to_maxindex을 초기화 수행
/* init some links before init_ISA_irqs() */
early_irq_init();
// irq_desc 0 ~ 15 까지의 object을 할당 받고 초기화를 수행
// allocated_irqs에 bit를 1로 세팅하고 radix tree에 각 irq_desc를 노트로 추가
init_IRQ();
// gic, combiner이 사용할 메모리 할당과 자료 구조 설정,
// gic irq (0~15), combiner irq (32~63) interrupt 를 enable 시킴
tick_init();
// tick 관련 mask 변수를 0으로 초기화 수행
init_timers();
// boot_tvec_bases의 맴버 값을 초기화하고 timers_nb를 cpu_notifier 에 등록,
// softirq_vec[1] 에 run_timer_softirq 등록하여 초기화 수행
hrtimers_init();
// hrtimer_bases의 맴버 값을 초기화하고 hrtimers_nb를 cpu_notifier 에 등록,
// softirq_vec[8] 에 run_hrtimer_softirq 등록하여 초기화 수행
softirq_init();
// tasklet_vec, tasklet_hi_vec 맴버 값을 초기화하고,
// softirq_vec[6]에 tasklet_action, softirq_vec[0]에 tasklet_hi_action 등록하여 초기화 수행
timekeeping_init();
// ntp 관련 전역변수 초기화, timekeeper, shadow_timekeeper의 맴버값 초기화 수행
time_init();
// timer 를 사용하기 위한 clk source, clk_table 메모리 할당 및 초기화,
// timer event를 위한 timer irq (MCT) 초기화 수행
sched_clock_postinit();
// sched_clock_timer을 초기화 수행
perf_event_init(); // null function
profile_init(); // null function
call_function_init();
// 각 cpu core에서 사용할 call_single_queue를 맴버값 초기화
// cfd_data 맴버값을 초기화하고 pcp에서 사용할 메모리 공간 할당
// cpu_chain에 hotplug_cfd_notifier 를 등록함
// irqs_disabled(): 1
WARN(!irqs_disabled(), "Interrupts were enabled early\n");
// early_boot_irqs_disabled: true
early_boot_irqs_disabled = false;
// early_boot_irqs_disabled: false
local_irq_enable();
// IRQ를 enable 함
kmem_cache_init_late(); // null function
/*
* HACK ALERT! This is early. We're enabling the console before
* we've done PCI setups etc, and console_init() must be aware of
* this. But we do want output early, in case something goes wrong.
*/
console_init();
// panic_later: NULL
if (panic_later)
panic(panic_later, panic_param);
lockdep_info(); // null function
/*
* Need to run this when irqs are enabled, because it wants
* to self-test [hard/soft]-irqs on/off lock inversion bugs
* too:
*/
locking_selftest(); // null function
#ifdef CONFIG_BLK_DEV_INITRD // CONFIG_BLK_DEV_INITRD=y
// initrd_start: NULL, initrd_below_start_ok: 0
if (initrd_start && !initrd_below_start_ok &&
page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) {
pr_crit("initrd overwritten (0x%08lx < 0x%08lx) - disabling it.\n",
page_to_pfn(virt_to_page((void *)initrd_start)),
min_low_pfn);
initrd_start = 0;
}
#endif
page_cgroup_init(); // null function
debug_objects_mem_init(); // null function
kmemleak_init(); // null function
setup_per_cpu_pageset();
// per cpu가 사용하는 pageset의 각각의 zone 맴버값 초기화 수행
numa_policy_init(); // null function
// late_time_init: NULL
if (late_time_init)
late_time_init();
sched_clock_init();
// sched_clock_running 값을 1 로 초기화 수행
calibrate_delay();
// BogoMIPS값을 결정하기위한 계산을 수행하고 결과를 출력함
pidmap_init();
// pidmap 을 사용하기 위한 초기화 수행
anon_vma_init();
// anon vma 를 사용하기 위한 kmem_cache 할당자 초기화 수행
#ifdef CONFIG_X86 // CONFIG_X86=n
if (efi_enabled(EFI_RUNTIME_SERVICES))
efi_enter_virtual_mode();
#endif
thread_info_cache_init(); // null function
cred_init();
// credentials 를 사용하기 위한 kmem_cache 할당자 초기화 수행
// totalram_pages: 총 free된 page 수
fork_init(totalram_pages);
// task_struct 를 사용하기 위한 kmem_cache 할당자 초기화 수행
// max_threads값을 계산하여 init_task에 threads값의 limit 값 설정함
proc_caches_init();
// sighand_struct, signal_struct, files_struct, fs_struct, mm_struct, vm_area_struct, nsproxy
// 를 사용하기 위한 kmem_cache 할당자 및 percpu list 초기화 수행
buffer_init();
// buffer_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);
// virtual file system을 위한 names, dentry, inode, filp, mount cache 생성 후
// file system 을 위한 초기화 수행 및 mount 수행, block, char dev 사용을 위한 초기화 수행
signals_init();
// signal을 사용하기 위한 kmem_cache 를 생성
/* rootfs populating might need page-writeback */
page_writeback_init();
// page writeback을 위한 global_dirty_limit, ratelimit_pages 값을 초기화 수행
#ifdef CONFIG_PROC_FS // CONFIG_PROC_FS=y
proc_root_init();
// proc filesystem을 등록 하고 proc을 사용하기 위한 dentry, inode 생성 후
// sysctl_base_table 에 등록된 kernel, vm, fs, debug, dev의 dir, files 를 recursive 하게 RB Tree 를 구성함
#endif
cgroup_init();
- call: start_kernel()
- cgroup_init()
- call: cgroup_init()
// ARM10C 20160716
int __init cgroup_init(void)
{
struct cgroup_subsys *ss;
unsigned long key;
int i, err;
// bdi_init(&cgroup_backing_dev_info): 0
err = bdi_init(&cgroup_backing_dev_info);
// err: 0
// bdi_init에서 한일:
// (&cgroup_backing_dev_info)->dev: NULL
// (&cgroup_backing_dev_info)->min_ratio: 0
// (&cgroup_backing_dev_info)->max_ratio: 100
// (&cgroup_backing_dev_info)->max_prop_frac: 0x400
// &(&cgroup_backing_dev_info)->wb_lock 을 이용한 spinlock 초기화 수행
// (&(&cgroup_backing_dev_info)->bdi_list)->next: &(&cgroup_backing_dev_info)->bdi_list
// (&(&cgroup_backing_dev_info)->bdi_list)->prev: &(&cgroup_backing_dev_info)->bdi_list
// (&(&cgroup_backing_dev_info)->work_list)->next: &(&cgroup_backing_dev_info)->work_list
// (&(&cgroup_backing_dev_info)->work_list)->prev: &(&cgroup_backing_dev_info)->work_list
//
// (&cgroup_backing_dev_info)->wb 의 맴버값을 0으로 초기화함
// (&(&cgroup_backing_dev_info)->wb)->bdi: &cgroup_backing_dev_info
// (&(&cgroup_backing_dev_info)->wb)->last_old_flush: XXX
// (&(&(&cgroup_backing_dev_info)->wb)->b_dirty)->next: &(&(&cgroup_backing_dev_info)->wb)->b_dirty
// (&(&(&cgroup_backing_dev_info)->wb)->b_dirty)->prev: &(&(&cgroup_backing_dev_info)->wb)->b_dirty
// (&(&(&cgroup_backing_dev_info)->wb)->b_io)->next: &(&(&cgroup_backing_dev_info)->wb)->b_io
// (&(&(&cgroup_backing_dev_info)->wb)->b_io)->prev: &(&(&cgroup_backing_dev_info)->wb)->b_io
// (&(&(&cgroup_backing_dev_info)->wb)->b_more_io)->next: &(&(&cgroup_backing_dev_info)->wb)->b_more_io
// (&(&(&cgroup_backing_dev_info)->wb)->b_more_io)->prev: &(&(&cgroup_backing_dev_info)->wb)->b_more_io
// &(&(&cgroup_backing_dev_info)->wb)->list_lock 을 이용한 spinlock 초기화 수행
// (&(&(&(&cgroup_backing_dev_info)->wb)->dwork)->work)->data: { 0xFFFFFFE0 }
// (&(&(&(&(&cgroup_backing_dev_info)->wb)->dwork)->work)->entry)->next: &(&(&(&(&cgroup_backing_dev_info)->wb)->dwork)->work)->entry
// (&(&(&(&(&cgroup_backing_dev_info)->wb)->dwork)->work)->entry)->prev: &(&(&(&(&cgroup_backing_dev_info)->wb)->dwork)->work)->entry
// (&(&(&(&cgroup_backing_dev_info)->wb)->dwork)->work)->func: bdi_writeback_workfn
// (&(&(&(&cgroup_backing_dev_info)->wb)->dwork)->timer)->entry.next: NULL
// (&(&(&(&cgroup_backing_dev_info)->wb)->dwork)->timer)->base: [pcp0] tvec_bases | 0x2
// (&(&(&(&cgroup_backing_dev_info)->wb)->dwork)->timer)->slack: -1
// (&(&(&(&cgroup_backing_dev_info)->wb)->dwork)->timer)->function = (delayed_work_timer_fn);
// (&(&(&(&cgroup_backing_dev_info)->wb)->dwork)->timer)->data = ((unsigned long)(&(&(&cgroup_backing_dev_info)->wb)->dwork));
//
// (&(&(&(&(&cgroup_backing_dev_info)->bdi_stat[0...3])->lock)->wait_lock)->rlock)->raw_lock: { { 0 } }
// (&(&(&(&(&cgroup_backing_dev_info)->bdi_stat[0...3])->lock)->wait_lock)->rlock)->magic: 0xdead4ead
// (&(&(&(&(&cgroup_backing_dev_info)->bdi_stat[0...3])->lock)->wait_lock)->rlock)->owner: 0xffffffff
// (&(&(&(&(&cgroup_backing_dev_info)->bdi_stat[0...3])->lock)->wait_lock)->rlock)->owner_cpu: 0xffffffff
// (&(&(&cgroup_backing_dev_info)->bdi_stat[0...3])->list)->next: &(&(&cgroup_backing_dev_info)->bdi_stat[0...3])->list
// (&(&(&cgroup_backing_dev_info)->bdi_stat[0...3])->list)->prev: &(&(&cgroup_backing_dev_info)->bdi_stat[0...3])->list
// (&(&cgroup_backing_dev_info)->bdi_stat[0...3])->count: 0
// (&(&cgroup_backing_dev_info)->bdi_stat[0...3])->counters: kmem_cache#26-o0 에서 할당된 4 bytes 메모리 주소
// list head 인 &percpu_counters에 &(&(&cgroup_backing_dev_info)->bdi_stat[0...3])->list를 연결함
//
// (&cgroup_backing_dev_info)->dirty_exceeded: 0
// (&cgroup_backing_dev_info)->bw_time_stamp: XXX
// (&cgroup_backing_dev_info)->written_stamp: 0
// (&cgroup_backing_dev_info)->balanced_dirty_ratelimit: 0x6400
// (&cgroup_backing_dev_info)->dirty_ratelimit: 0x6400
// (&cgroup_backing_dev_info)->write_bandwidth: 0x6400
// (&cgroup_backing_dev_info)->avg_write_bandwidth: 0x6400
//
// (&(&(&(&(&(&cgroup_backing_dev_info)->completions)->events)->lock)->wait_lock)->rlock)->raw_lock: { { 0 } }
// (&(&(&(&(&(&cgroup_backing_dev_info)->completions)->events)->lock)->wait_lock)->rlock)->magic: 0xdead4ead
// (&(&(&(&(&(&cgroup_backing_dev_info)->completions)->events)->lock)->wait_lock)->rlock)->owner: 0xffffffff
// (&(&(&(&(&(&cgroup_backing_dev_info)->completions)->events)->lock)->wait_lock)->rlock)->owner_cpu: 0xffffffff
// (&(&(&(&cgroup_backing_dev_info)->completions)->events)->list)->next: &(&(&(&cgroup_backing_dev_info)->completions)->events)->list
// (&(&(&(&cgroup_backing_dev_info)->completions)->events)->list)->prev: &(&(&(&cgroup_backing_dev_info)->completions)->events)->list
// (&(&(&cgroup_backing_dev_info)->completions)->events)->count: 0
// (&(&(&cgroup_backing_dev_info)->completions)->events)->counters: kmem_cache#26-o0 에서 할당된 4 bytes 메모리 주소
// list head 인 &percpu_counters에 &(&(&(&cgroup_backing_dev_info)->completions)->events)->list를 연결함
// (&(&cgroup_backing_dev_info)->completions)->period: 0
// &(&(&cgroup_backing_dev_info)->completions)->lock을 이용한 spinlock 초기화 수행
// err: 0
if (err)
return err;
// CGROUP_BUILTIN_SUBSYS_COUNT: 4
for_each_builtin_subsys(ss, i) {
// for ((i) = 0; (i) < CGROUP_BUILTIN_SUBSYS_COUNT && (((ss) = cgroup_subsys[i]) || true); (i)++)
// i: 0, cgroup_subsys[0]: &debug_subsys, ss: &debug_subsys, ss->early_init: (&debug_subsys)->early_init: NULL
// i: 1, cgroup_subsys[1]: &cpu_cgroup_subsys, ss: &cpu_cgroup_subsys, ss->early_init: (&cpu_cgroup_subsys)->early_init: 1
// i: 2, cgroup_subsys[2]: &cpuacct_subsys, ss: &cpuacct_subsys, ss->early_init: (&cpuacct_subsys)->early_init: 1
// i: 3, cgroup_subsys[3]: &freezer_subsys, ss: &freezer_subsys, ss->early_init: (&freezer_subsys)->early_init: 0
if (!ss->early_init)
// ss: &debug_subsys
// ss: &freezer_subsys
cgroup_init_subsys(ss);
// cgroup_init_subsys(&debug_subsys) 에서 한일:
// (&(&debug_subsys)->cftsets)->next: &(&debug_subsys)->cftsets
// (&(&debug_subsys)->cftsets)->prev: &(&debug_subsys)->cftsets
//
// (&debug_files[0])->ss: &debug_subsys
// (&debug_files[1])->ss: &debug_subsys
// (&debug_files[2])->ss: &debug_subsys
// (&debug_files[3])->ss: &debug_subsys
// (&debug_files[4])->ss: &debug_subsys
// (&debug_files[5])->ss: &debug_subsys
// (&debug_subsys)->base_cftset.cfts: debug_files
//
// HEAD list인 &(&debug_subsys)->cftsets에 &(&debug_subsys)->base_cftset.node을 tail에 추가
//
// HEAD list인 &cgroup_dummy_root.subsys_list에 &(&debug_subsys)->sibling을 추가
//
// (&debug_subsys)->root: &cgroup_dummy_root
//
// (kmem_cache#30-oX (struct cgroup_subsys_state))->cgroup: &cgroup_dummy_root.top_cgroup
// (kmem_cache#30-oX (struct cgroup_subsys_state))->ss: &debug_subsys
// (kmem_cache#30-oX (struct cgroup_subsys_state))->flags: 1
//
// init_css_set.subsys[0]: kmem_cache#30-oX (struct cgroup_subsys_state)
//
// need_forkexit_callback: 1
//
// (kmem_cache#30-oX (struct cgroup_subsys_state))->flags: 0x3
// (&cgroup_dummy_root.top_cgroup)->nr_css: 3
// (&cgroup_dummy_root.top_cgroup)->subsys[0]: kmem_cache#30-oX (struct cgroup_subsys_state)
// cgroup_init_subsys(&freezer_subsys) 에서 한일:
// (&(&freezer_subsys)->cftsets)->next: &(&freezer_subsys)->cftsets
// (&(&freezer_subsys)->cftsets)->prev: &(&freezer_subsys)->cftsets
//
// (&files[0])->ss: &freezer_subsys
// (&files[1])->ss: &freezer_subsys
// (&files[2])->ss: &freezer_subsys
// (&freezer_subsys)->base_cftset.cfts: files
//
// HEAD list인 &(&freezer_subsys)->cftsets에 &(&freezer_subsys)->base_cftset.node을 tail에 추가
//
// HEAD list인 &cgroup_dummy_root.subsys_list에 &(&freezer_subsys)->sibling을 추가
// (&freezer_subsys)->root: &cgroup_dummy_root
//
// struct freezer 만큼 메모리를 할당 받음 kmem_cache#29-oX (struct freezer)
//
// (&(kmem_cache#29-oX (struct freezer))->lock)->raw_lock: { { 0 } }
// (&(kmem_cache#29-oX (struct freezer))->lock)->magic: 0xdead4ead
// (&(kmem_cache#29-oX (struct freezer))->lock)->owner: 0xffffffff
// (&(kmem_cache#29-oX (struct freezer))->lock)->owner_cpu: 0xffffffff
//
// (&(kmem_cache#29-oX (struct freezer))->css)->cgroup: &cgroup_dummy_root.top_cgroup
// (&(kmem_cache#29-oX (struct freezer))->css)->ss: &freezer_subsys
// (&(kmem_cache#29-oX (struct freezer))->css)->flags: 1
//
// init_css_set.subsys[3]: &(kmem_cache#29-oX (struct freezer))->css
//
// need_forkexit_callback: 1
//
// (kmem_cache#29-oX (struct freezer))->state: 1
// (&(kmem_cache#29-oX (struct freezer))->css)->flags: 0x3
// (&cgroup_dummy_root.top_cgroup)->nr_css: 4
// (&cgroup_dummy_root.top_cgroup)->subsys[3]: &(kmem_cache#29-oX (struct freezer))->css
}
/* allocate id for the dummy hierarchy */
mutex_lock(&cgroup_mutex);
// mutex_lock에서 한일:
// &cgroup_mutex 을 사용하여 mutex lock을 수행
mutex_lock(&cgroup_root_mutex);
// mutex_lock에서 한일:
// &cgroup_root_mutex 을 사용하여 mutex lock을 수행
/* Add init_css_set to the hash table */
// css_set_hash(init_css_set.subsys): 0xXXXXXXXX
key = css_set_hash(init_css_set.subsys);
// key: 0xXXXXXXXX
// css_set_hash 에서 한일:
// init_css_set.subsys 를 이용하여 hash key 값 생성, key: 0xXXXXXXXX
// 2016/07/23 종료
hash_add(css_set_table, &init_css_set.hlist, key);## log
- start_kernel()
- cgroup_inti()
- call: cgroup_init()
- bdi_init()
- for_each_buildtin_subsys()
- cgroup_init_subsys(ss): ss=cgroup_subsys
- mutex_lock(&cgroup_mutex)
- mutex_lock(&cgroup_root_mutex)
- key = css_set_hash(init_css_set.subsys)
- hash_add(css_set_table, &init_css_set.hlist, key)
#define hash_add(hashtable, node, key) \
hlist_add_head(node, &hashtable[hash_min(key, HASH_BITS(hashtable))])
- hash_min()
#define hash_min(val, bits) \
(sizeof(val) <= 4 ? hash_32(val, bits) : hash_long(val, bits))
- hash_32()
// ARM10C 20160116
// ptr: NULL, bits: 31
static inline u32 hash_32(u32 val, unsigned int bits)
{
/* On some cpus multiply is faster, on others gcc will do shifts */
// val: &(kmem_cache#4-oX)->i_state 값을 이용한 hash val 값, GOLDEN_RATIO_PRIME_32: 0x9e370001UL
u32 hash = val * GOLDEN_RATIO_PRIME_32;
// hash: &(kmem_cache#4-oX)->i_state 값을 이용한 hash val 값* 0x9e370001UL
/* High bits are more random, so use them. */
// hash: &(kmem_cache#4-oX)->i_state 값을 이용한 hash val 값* 0x9e370001UL,
// bits: (&(kmem_cache#4-oX)->i_state의 zone의 주소)->wait_table_bits
return hash >> (32 - bits);
// return 계산된 hash index 값
}
- hash_long()
#define hash_long(val, bits) hash_32(val, bits)
- hlist_add_head()
// ARM10C 20151219
// &dentry->d_alias: (kmem_cache#5-oX)->d_alias, &inode->i_dentry: &(kmem_cache#4-oX)->i_dentry
static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
{
// h->first: (&clk_root_list)->first: NULL
// h->first: (&(kmem_cache#29-oX (fin_pll))->children)->first: NULL
// h->first: (&clk_orphan_list)->first: NULL
struct hlist_node *first = h->first;
// first: NULL
// first: NULL
// first: NULL
// n->next: (&(kmem_cache#29-oX)->child_node)->next, first: NULL
// n->next: (&(kmem_cache#29-oX (apll))->child_node)->next, first: NULL
// n->next: (&(kmem_cache#29-oX (mout_mspll_kfc))->child_node)->next, first: NULL
n->next = first;
// n->next: (&(kmem_cache#29-oX)->child_node)->next: NULL
// n->next: (&(kmem_cache#29-oX (apll))->child_node)->next: NULL
// n->next: (&(kmem_cache#29-oX (mout_mspll_kfc))->child_node)->next: NULL
// first: NULL
// first: NULL
// first: NULL
if (first)
first->pprev = &n->next;
// h->first: (&clk_root_list)->first: NULL, n: &(kmem_cache#29-oX)->child_node
// h->first: (&(kmem_cache#29-oX (fin_pll))->children)->first: NULL, n: &(kmem_cache#29-oX (apll))->child_node
// h->first: (&clk_orphan_list)->first: NULL, n: &(kmem_cache#29-oX (mout_mspll_kfc))->child_node
h->first = n;
// h->first: (&clk_root_list)->first: &(kmem_cache#29-oX)->child_node
// h->first: (&(kmem_cache#29-oX (fin_pll))->children)->first: &(kmem_cache#29-oX (apll))->child_node
// h->first: (&clk_orphan_list)->first: &(kmem_cache#29-oX (mout_mspll_kfc))->child_node
// n->pprev: (&(kmem_cache#29-oX)->child_node)->pprev,
// &h->first: &(&clk_root_list)->first: &(&(kmem_cache#29-oX)->child_node)
// n->pprev: (&(kmem_cache#29-oX (apll))->child_node)->pprev,
// &h->first: &(&(kmem_cache#29-oX (fin_pll))->children)->first: &(&(kmem_cache#29-oX (apll))->child_node)
// n->pprev: (&(kmem_cache#29-oX (mout_mspll_kfc))->child_node)->pprev,
// &h->first: (&clk_orphan_list)->first: &(&(kmem_cache#29-oX (mout_mspll_kfc))->child_node)
n->pprev = &h->first;
// n->pprev: (&(kmem_cache#29-oX)->child_node)->pprev: &(&(kmem_cache#29-oX)->child_node)
// n->pprev: (&(kmem_cache#29-oX (apll))->child_node)->pprev: &(&(kmem_cache#29-oX (apll))->child_node)
// n->pprev: (&(kmem_cache#29-oX (mout_mspll_kfc))->child_node)->pprev: &(&(kmem_cache#29-oX (mout_mspll_kfc))->child_node)
}
-
start_kernel()
- cgroup_init()
-
call: cgroup_init()
- bdi_init()
- for_each_buildtin_subsys()
- cgroup_init_subsys(ss): ss=cgroup_subsys
- mutex_lock(&cgroup_mutex)
- mutex_lock(&cgroup_root_mutex)
- key = css_set_hash(init_css_set.subsys)
- hash_add(css_set_table, &init_css_set.hlist, key)
// ARM10C 20160716
int __init cgroup_init(void)
{
struct cgroup_subsys *ss;
unsigned long key;
int i, err;
// bdi_init(&cgroup_backing_dev_info): 0
err = bdi_init(&cgroup_backing_dev_info);
// err: 0
// err: 0
if (err)
return err;
// CGROUP_BUILTIN_SUBSYS_COUNT: 4
for_each_builtin_subsys(ss, i) {
// for ((i) = 0; (i) < CGROUP_BUILTIN_SUBSYS_COUNT && (((ss) = cgroup_subsys[i]) || true); (i)++)
// i: 0, cgroup_subsys[0]: &debug_subsys, ss: &debug_subsys, ss->early_init: (&debug_subsys)->early_init: NULL
// i: 1, cgroup_subsys[1]: &cpu_cgroup_subsys, ss: &cpu_cgroup_subsys, ss->early_init: (&cpu_cgroup_subsys)->early_init: 1
// i: 2, cgroup_subsys[2]: &cpuacct_subsys, ss: &cpuacct_subsys, ss->early_init: (&cpuacct_subsys)->early_init: 1
// i: 3, cgroup_subsys[3]: &freezer_subsys, ss: &freezer_subsys, ss->early_init: (&freezer_subsys)->early_init: 0
if (!ss->early_init)
// ss: &debug_subsys
// ss: &freezer_subsys
cgroup_init_subsys(ss);
}
/* allocate id for the dummy hierarchy */
mutex_lock(&cgroup_mutex);
// mutex_lock에서 한일:
// &cgroup_mutex 을 사용하여 mutex lock을 수행
mutex_lock(&cgroup_root_mutex);
// mutex_lock에서 한일:
// &cgroup_root_mutex 을 사용하여 mutex lock을 수행
/* Add init_css_set to the hash table */
// css_set_hash(init_css_set.subsys): 0xXXXXXXXX
key = css_set_hash(init_css_set.subsys);
// key: 0xXXXXXXXX
// css_set_hash 에서 한일:
// init_css_set.subsys 를 이용하여 hash key 값 생성, key: 0xXXXXXXXX
// 2016/07/23 종료
hash_add(css_set_table, &init_css_set.hlist, key);
BUG_ON(cgroup_init_root_id(&cgroup_dummy_root, 0, 1));
err = idr_alloc(&cgroup_dummy_root.cgroup_idr, cgroup_dummy_top,
0, 1, GFP_KERNEL);
6caa0f4..7eacb30 master -> origin/master
Updating 6caa0f4..7eacb30
Fast-forward
arch/arm/include/asm/atomic.h | 4 +
fs/namespace.c | 1 +
fs/sysfs/dir.c | 136 +++++++++++++++++++-
fs/sysfs/sysfs.h | 2 +
include/asm-generic/bitops/non-atomic.h | 2 +
include/asm-generic/bitsperlong.h | 1 +
include/linux/bitmap.h | 11 ++
include/linux/cgroup.h | 2 +
include/linux/gfp.h | 3 +
include/linux/hash.h | 2 +
include/linux/hashtable.h | 24 ++++
include/linux/idr.h | 46 +++++++
include/linux/kernel.h | 5 +
include/linux/kobject.h | 4 +
include/linux/kobject_ns.h | 2 +
include/linux/kref.h | 7 ++
include/linux/list.h | 3 +
include/linux/lockdep.h | 2 +
include/linux/log2.h | 2 +
include/linux/rcupdate.h | 4 +
include/linux/slab.h | 2 +
include/linux/types.h | 2 +
include/uapi/asm-generic/errno-base.h | 2 +
kernel/cgroup.c | 117 ++++++++++++++++-
lib/bitmap.c | 14 +++
lib/idr.c | 217 +++++++++++++++++++++++++++++++-
lib/kobject.c | 99 ++++++++++++++-
27 files changed, 707 insertions(+), 9 deletions(-)
aa761a9..f59245c master -> origin/master
Updating aa761a9..f59245c
Fast-forward
arch/arm/include/asm/bugs.h | 3 +-
arch/arm/include/asm/page.h | 1 +
arch/arm/include/asm/pgtable-2level.h | 5 +
arch/arm/include/asm/pgtable.h | 5 +
arch/arm/mm/fault-armv.c | 13 ++
arch/arm/mm/mmu.c | 1 +
fs/filesystems.c | 21 +++
fs/sysfs/dir.c | 213 ++++++++++++++++++++++++-
fs/sysfs/mount.c | 10 ++
fs/sysfs/sysfs.h | 10 ++
include/linux/cpuset.h | 1 +
include/linux/delayacct.h | 3 +-
include/linux/efi.h | 7 +-
include/linux/ftrace.h | 3 +-
include/linux/gfp.h | 7 +
include/linux/kernel.h | 1 +
include/linux/mm_types.h | 1 +
include/linux/proc_fs.h | 2 +
include/linux/rbtree.h | 3 +
include/linux/sfi.h | 3 +-
include/linux/taskstats_kern.h | 3 +-
include/linux/vmalloc.h | 4 +
include/uapi/linux/const.h | 1 +
init/main.c | 21 ++-
kernel/cgroup.c | 134 ++++++++++++++++
lib/kobject.c | 284 +++++++++++++++++++++++++++++++++-
lib/rbtree.c | 3 +
mm/vmalloc.c | 32 ++++
28 files changed, 771 insertions(+), 24 deletions(-)