Skip to content

Latest commit

 

History

History
1145 lines (972 loc) · 41.9 KB

File metadata and controls

1145 lines (972 loc) · 41.9 KB
Neuromancer : 152 주차
일시 : 2016.07.23 (152주차 스터디 진행)
모임명 : neuromancer.kr
장소 : 토즈 서현점
장소지원 : 공개 소프트웨어 개발자 커뮤니티 지원 프로그램
참여인원 : 3명

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

152주차 진도

  • ᇂ152차 시작 위치
    • start_kernel 1 ~/init/main.c
    • cgroup_init 941 ~/init/main.c
    • cgroup_init_subsys 5922 cgroup_init_subsys(ss);
    • online_css 5400 BUG_ON(online_css(css));
    • freezer_css_online 4596 // freezer_css_online(&(kmem_cache#29-o0 (struct freezer))->css): 0

152 주차 함수 호출 구조

  • 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
  • call: cgroup_init_subsys(): ss: &debug_subsys
  • call: cgroup_init_subsys(): ss: &freezer_subsys

start_kernel()

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

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

  • call: start_kernel()
  • cgroup_init()
  • call: cgroup_init()
  • bdi_init()
  • for_each_buildtin_subsys()
    • cgroup_init_subsys(ss): ss=cgroup_subsys
  • call: cgroup_init_subsys(): ss: &debug_subsys
  • call: cgroup_init_subsys(): ss: &freezer_subsys
// ARM10C 20160716
// ss: &freezer_subsys
static void __init cgroup_init_subsys(struct cgroup_subsys *ss)
{
	struct cgroup_subsys_state *css;

	// ss->name: (&freezer_subsys)->name: "freezer"
	printk(KERN_INFO "Initializing cgroup subsys %s\n", ss->name);
	// "Initializing cgroup subsys freezer\n"

	mutex_lock(&cgroup_mutex);
	// mutex_lock에서 한일:
	// &cgroup_mutex 을 사용하여 mutex lock을 수행

	/* init base cftset */
	// ss: &freezer_subsys
	cgroup_init_cftsets(ss);

	// cgroup_init_cftsets(&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에 추가

	/* Create the top cgroup state for this subsystem */
	// &ss->sibling: &(&freezer_subsys)->sibling
	list_add(&ss->sibling, &cgroup_dummy_root.subsys_list);
	// list_add에서 한일:
	// HEAD list인 &cgroup_dummy_root.subsys_list에 &(&freezer_subsys)->sibling을 추가

	// ss->root: (&freezer_subsys)->root
	ss->root = &cgroup_dummy_root;
	// ss->root: (&freezer_subsys)->root: &cgroup_dummy_root

	// ss->css_alloc: (&freezer_subsys)->css_alloc: freezer_css_alloc
	// cgroup_dummy_top: &cgroup_dummy_root.top_cgroup, ss: &freezer_subsys
	// cgroup_css(&cgroup_dummy_root.top_cgroup, &freezer_subsys): (&cgroup_dummy_root.top_cgroup)->subsys[3]
	// freezer_css_alloc((&cgroup_dummy_root.top_cgroup)->subsys[3]): &(kmem_cache#29-o0 (struct freezer))->css
	css = ss->css_alloc(cgroup_css(cgroup_dummy_top, ss));
	// css: &(kmem_cache#29-o0 (struct freezer))->css

	// freezer_css_alloc 에서 한일:
	// struct freezer 만큼 메모리를 할당 받음 kmem_cache#29-o0 (struct freezer)
	//
	// (&(kmem_cache#29-o0 (struct freezer))->lock)->raw_lock: { { 0 } }
	// (&(kmem_cache#29-o0 (struct freezer))->lock)->magic: 0xdead4ead
	// (&(kmem_cache#29-o0 (struct freezer))->lock)->owner: 0xffffffff
	// (&(kmem_cache#29-o0 (struct freezer))->lock)->owner_cpu: 0xffffffff

	/* We don't handle early failures gracefully */
	// css: &(kmem_cache#29-o0 (struct freezer))->css, IS_ERR(&(kmem_cache#29-o0 (struct freezer))->css): 0
	BUG_ON(IS_ERR(css));

	// css: &(kmem_cache#29-o0 (struct freezer))->css, ss: &freezer_subsys, cgroup_dummy_top: &cgroup_dummy_root.top_cgroup
	init_css(css, ss, cgroup_dummy_top);

	// init_css(&(kmem_cache#29-o0 (struct freezer))->css)에서 한일:
	// (&(kmem_cache#29-o0 (struct freezer))->css)->cgroup: &cgroup_dummy_root.top_cgroup
	// (&(kmem_cache#29-o0 (struct freezer))->css)->ss: &freezer_subsys
	// (&(kmem_cache#29-o0 (struct freezer))->css)->flags: 1

	/* Update the init_css_set to contain a subsys
	 * pointer to this state - since the subsystem is
	 * newly registered, all tasks and hence the
	 * init_css_set is in the subsystem's top cgroup. */
	// ss->subsys_id: (&freezer_subsys)->subsys_id: 3, css: &(kmem_cache#29-o0 (struct freezer))->css
	init_css_set.subsys[ss->subsys_id] = css;
	// init_css_set.subsys[3]: &(kmem_cache#29-o0 (struct freezer))->css

	// need_forkexit_callback: 1, ss->fork: (&freezer_subsys)->fork: freezer_fork, ss->exit: (&freezer_subsys)->exit: NULL
	need_forkexit_callback |= ss->fork || ss->exit;
	// need_forkexit_callback: 1

	/* At system boot, before all subsystems have been
	 * registered, no tasks have been forked, so we don't
	 * need to invoke fork callbacks here. */
	// list_empty(&init_task.tasks): 1
	BUG_ON(!list_empty(&init_task.tasks));

	// css: &root_task_group.css, online_css(&root_task_group.css): 0
	// css: &root_cpuacct.css, online_css(&root_cpuacct.css): 0
	// css: kmem_cache#30-oX (struct cgroup_subsys_state), online_css(kmem_cache#30-oX (struct cgroup_subsys_state)): 0
	//
	// css: &(kmem_cache#29-o0 (struct freezer))->css, online_css(&(kmem_cache#29-o0 (struct freezer))->css): 0
	BUG_ON(online_css(css));


	mutex_unlock(&cgroup_mutex);

	// mutex_unlock에서 한일:
	// &cgroup_mutex 을 사용하여 mutex unlock을 수행

	/* this function shouldn't be used with modular subsystems, since they
	 * need to register a subsys_id, among other things */
	// ss->module: (&cpu_cgroup_subsys)->module: NULL
	// ss->module: (&cpuacct_subsys)->module: NULL
	// ss->module: (&debug_subsys)->module: NULL
	// ss->module: (&freezer_subsys)->module: NULL	
	BUG_ON(ss->module);
}

init_css()

  • call: start_kernel()
  • cgroup_init()
  • call: cgroup_init()
  • bdi_init()
  • for_each_buildtin_subsys()
    • cgroup_init_subsys(ss): ss=cgroup_subsys
  • call: cgroup_init_subsys(): ss: &debug_subsys
  • call: cgroup_init_subsys(): ss: &freezer_subsys
  • printk()
  • mutex_lock(&cgroup_mutex)
  • cgroup_init_cftsets(ss); // ss: &freezer_subsys
  • list_add(&ss->sibling, &cgroup_dummy_root.subsys_list);
  • css = ss->css_alloc(cgroup_css(cgroup_dummy_top, ss));
  • BUG_ON(IS_ERR(css));
  • init_css(css, ss, cgroup_dummy_top);
  • call: init_css()
// ARM10C 20160716
// css: &(kmem_cache#29-o0 (struct freezer))->css, ss: &freezer_subsys, cgroup_dummy_top: &cgroup_dummy_root.top_cgroup
static void init_css(struct cgroup_subsys_state *css, struct cgroup_subsys *ss,
		     struct cgroup *cgrp)
{
	// css->cgroup: (&root_task_group.css)->cgroup, cgrp: &cgroup_dummy_root.top_cgroup
	// css->cgroup: (&root_cpuacct.css)->cgroup, cgrp: &cgroup_dummy_root.top_cgroup
	css->cgroup = cgrp;
	// css->cgroup: (&root_task_group.css)->cgroup: &cgroup_dummy_root.top_cgroup
	// css->cgroup: (&root_cpuacct.css)->cgroup: &cgroup_dummy_root.top_cgroup

	// css->ss: (&root_task_group.css)->ss, ss: &cpu_cgroup_subsys
	// css->ss: (&root_cpuacct.css)->ss, ss: &cpuacct_subsys
	css->ss = ss;
	// css->ss: (&root_task_group.css)->ss: &cpu_cgroup_subsys
	// css->ss: (&root_cpuacct.css)->ss: &cpuacct_subsys

	// css->flags: (&root_task_group.css)->flags
	// css->flags: (&root_cpuacct.css)->flags
	css->flags = 0;
	// css->flags: (&root_task_group.css)->flags: 0
	// css->flags: (&root_cpuacct.css)->flags: 0

	// cgrp->parent: (&cgroup_dummy_root.top_cgroup)->parent: NULL
	// cgrp->parent: (&cgroup_dummy_root.top_cgroup)->parent: NULL
	if (cgrp->parent)
		css->parent = cgroup_css(cgrp->parent, ss);
	else
		// css->flags: (&root_task_group.css)->flags: 0, CSS_ROOT: 1
		// css->flags: (&root_cpuacct.css)->flags: 0, CSS_ROOT: 1
		css->flags |= CSS_ROOT;
		// css->flags: (&root_task_group.css)->flags: 1
		// css->flags: (&root_cpuacct.css)->flags: 1

	// cgrp: &cgroup_dummy_root.top_cgroup, ss: &cpu_cgroup_subsys
	// cgroup_css(&cgroup_dummy_root.top_cgroup, &cpu_cgroup_subsys): (&cgroup_dummy_root.top_cgroup)->subsys[1]: NULL
	// cgrp: &cgroup_dummy_root.top_cgroup, ss: &cpuacct_subsys
	// cgroup_css(&cgroup_dummy_root.top_cgroup, &cpuacct_subsys): (&cgroup_dummy_root.top_cgroup)->subsys[2]: NULL
	BUG_ON(cgroup_css(cgrp, ss));
}

cgroup_init_subsys()

  • call: start_kernel()
  • cgroup_init()
  • call: cgroup_init()
  • bdi_init()
  • for_each_buildtin_subsys()
    • cgroup_init_subsys(ss): ss=cgroup_subsys
  • call: cgroup_init_subsys(): ss: &debug_subsys
  • call: cgroup_init_subsys(): ss: &freezer_subsys
  • printk()
  • mutex_lock(&cgroup_mutex)
  • cgroup_init_cftsets(ss); // ss: &freezer_subsys
  • list_add(&ss->sibling, &cgroup_dummy_root.subsys_list);
  • css = ss->css_alloc(cgroup_css(cgroup_dummy_top, ss));
  • BUG_ON(IS_ERR(css));
  • init_css(css, ss, cgroup_dummy_top);
  • !list_empty(&init_task.tasks)
  • online_css(css)
// ARM10C 20160716
// ss: &freezer_subsys
static void __init cgroup_init_subsys(struct cgroup_subsys *ss)
{
	struct cgroup_subsys_state *css;

	// ss->name: (&cpu_cgroup_subsys)->name: "cpu"
	// ss->name: (&cpuacct_subsys)->name: "cpuacct"
	// ss->name: (&debug_subsys)->name: "debug"
	// ss->name: (&freezer_subsys)->name: "freezer"
	printk(KERN_INFO "Initializing cgroup subsys %s\n", ss->name);
	// "Initializing cgroup subsys cpu\n"
	// "Initializing cgroup subsys cpuacct\n"
	// "Initializing cgroup subsys debug\n"
	// "Initializing cgroup subsys freezer\n"

	mutex_lock(&cgroup_mutex);

	// mutex_lock에서 한일:
	// &cgroup_mutex 을 사용하여 mutex lock을 수행

	// mutex_lock에서 한일:
	// &cgroup_mutex 을 사용하여 mutex lock을 수행

	// mutex_lock에서 한일:
	// &cgroup_mutex 을 사용하여 mutex lock을 수행

	// mutex_lock에서 한일:
	// &cgroup_mutex 을 사용하여 mutex lock을 수행

	/* init base cftset */
	// ss: &cpu_cgroup_subsys
	// ss: &cpuacct_subsys
	// ss: &debug_subsys
	// ss: &freezer_subsys
	cgroup_init_cftsets(ss);

	// cgroup_init_cftsets(&cpu_cgroup_subsys)에서 한일:
	// (&(&cpu_cgroup_subsys)->cftsets)->next: &(&cpu_cgroup_subsys)->cftsets
	// (&(&cpu_cgroup_subsys)->cftsets)->prev: &(&cpu_cgroup_subsys)->cftsets
	//
	// (&cpu_files[0])->ss: &cpu_cgroup_subsys
	// (&cpu_files[1])->ss: &cpu_cgroup_subsys
	// (&cpu_files[2])->ss: &cpu_cgroup_subsys
	// (&cpu_cgroup_subsys)->base_cftset.cfts: cpu_files
	//
	// HEAD list인 &(&cpu_cgroup_subsys)->cftsets에 &(&cpu_cgroup_subsys)->base_cftset.node을 tail에 추가

	// cgroup_init_cftsets(&cpuacct_subsys)에서 한일:
	// (&(&cpuacct_subsys)->cftsets)->next: &(&cpuacct_subsys)->cftsets
	// (&(&cpuacct_subsys)->cftsets)->prev: &(&cpuacct_subsys)->cftsets
	//
	// (&files[0])->ss: &cpuacct_subsys
	// (&files[1])->ss: &cpuacct_subsys
	// (&files[2])->ss: &cpuacct_subsys
	// (&cpuacct_subsys)->base_cftset.cfts: files
	//
	// HEAD list인 &(&cpuacct_subsys)->cftsets에 &(&cpuacct_subsys)->base_cftset.node을 tail에 추가

	// cgroup_init_cftsets(&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에 추가

	// cgroup_init_cftsets(&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에 추가

	/* Create the top cgroup state for this subsystem */
	// &ss->sibling: &(&cpu_cgroup_subsys)->sibling
	// &ss->sibling: &(&cpuacct_subsys)->sibling
	// &ss->sibling: &(&debug_subsys)->sibling
	// &ss->sibling: &(&freezer_subsys)->sibling
	list_add(&ss->sibling, &cgroup_dummy_root.subsys_list);

	// list_add에서 한일:
	// HEAD list인 &cgroup_dummy_root.subsys_list에 &(&cpu_cgroup_subsys)->sibling을 추가

	// list_add에서 한일:
	// HEAD list인 &cgroup_dummy_root.subsys_list에 &(&cpuacct_subsys)->sibling을 추가

	// list_add에서 한일:
	// HEAD list인 &cgroup_dummy_root.subsys_list에 &(&debug_subsys)->sibling을 추가

	// list_add에서 한일:
	// HEAD list인 &cgroup_dummy_root.subsys_list에 &(&freezer_subsys)->sibling을 추가

	// ss->root: (&cpu_cgroup_subsys)->root
	// ss->root: (&cpuacct_subsys)->root
	// ss->root: (&debug_subsys)->root
	// ss->root: (&freezer_subsys)->root
	ss->root = &cgroup_dummy_root;
	// ss->root: (&cpu_cgroup_subsys)->root: &cgroup_dummy_root
	// ss->root: (&cpuacct_subsys)->root: &cgroup_dummy_root
o	// ss->root: (&debug_subsys)->root: &cgroup_dummy_root
	// ss->root: (&freezer_subsys)->root: &cgroup_dummy_root

	// ss->css_alloc: (&cpu_cgroup_subsys)->css_alloc: cpu_cgroup_css_alloc
	// cgroup_dummy_top: &cgroup_dummy_root.top_cgroup, ss: &cpu_cgroup_subsys
	// cgroup_css(&cgroup_dummy_root.top_cgroup, &cpu_cgroup_subsys): (&cgroup_dummy_root.top_cgroup)->subsys[1]
	// cpu_cgroup_css_alloc((&cgroup_dummy_root.top_cgroup)->subsys[1]): &root_task_group.css
	// ss->css_alloc: (&cpuacct_subsys)->css_alloc: cpuacct_css_alloc
	// cgroup_dummy_top: &cgroup_dummy_root.top_cgroup, ss: &cpuacct_subsys
	// cgroup_css(&cgroup_dummy_root.top_cgroup, &cpuacct_subsys): (&cgroup_dummy_root.top_cgroup)->subsys[2]
	// cpuacct_css_alloc((&cgroup_dummy_root.top_cgroup)->subsys[2]): &root_cpuacct.css
	// ss->css_alloc: (&debug_subsys)->css_alloc: debug_css_alloc
	// cgroup_dummy_top: &cgroup_dummy_root.top_cgroup, ss: &debug_subsys
	// cgroup_css(&cgroup_dummy_root.top_cgroup, &debug_subsys): (&cgroup_dummy_root.top_cgroup)->subsys[0]
	// debug_css_alloc((&cgroup_dummy_root.top_cgroup)->subsys[0]): kmem_cache#30-oX (struct cgroup_subsys_state)
	// ss->css_alloc: (&freezer_subsys)->css_alloc: freezer_css_alloc
	// cgroup_dummy_top: &cgroup_dummy_root.top_cgroup, ss: &freezer_subsys
	// cgroup_css(&cgroup_dummy_root.top_cgroup, &freezer_subsys): (&cgroup_dummy_root.top_cgroup)->subsys[3]
	// freezer_css_alloc((&cgroup_dummy_root.top_cgroup)->subsys[3]): &(kmem_cache#29-o0 (struct freezer))->css
	css = ss->css_alloc(cgroup_css(cgroup_dummy_top, ss));
	// css: &root_task_group.css
	// css: &root_cpuacct.css
	// css: kmem_cache#30-oX (struct cgroup_subsys_state)
	// css: &(kmem_cache#29-o0 (struct freezer))->css

	// freezer_css_alloc 에서 한일:
	// struct freezer 만큼 메모리를 할당 받음 kmem_cache#29-o0 (struct freezer)
	//
	// (&(kmem_cache#29-o0 (struct freezer))->lock)->raw_lock: { { 0 } }
	// (&(kmem_cache#29-o0 (struct freezer))->lock)->magic: 0xdead4ead
	// (&(kmem_cache#29-o0 (struct freezer))->lock)->owner: 0xffffffff
	// (&(kmem_cache#29-o0 (struct freezer))->lock)->owner_cpu: 0xffffffff

	/* We don't handle early failures gracefully */
	// css: &root_task_group.css, IS_ERR(&root_task_group.css): 0
	// css: &root_cpuacct.css, IS_ERR(&root_cpuacct.css): 0
	// css: kmem_cache#30-oX (struct cgroup_subsys_state), IS_ERR(kmem_cache#30-oX (struct cgroup_subsys_state)): 0
	// css: &(kmem_cache#29-o0 (struct freezer))->css, IS_ERR(&(kmem_cache#29-o0 (struct freezer))->css): 0
	BUG_ON(IS_ERR(css));

	// css: &root_task_group.css, ss: &cpu_cgroup_subsys, cgroup_dummy_top: &cgroup_dummy_root.top_cgroup
	// css: &root_cpuacct.css, ss: &cpuacct_subsys, cgroup_dummy_top: &cgroup_dummy_root.top_cgroup
	// css: kmem_cache#30-oX (struct cgroup_subsys_state), ss: &debug_subsys, cgroup_dummy_top: &cgroup_dummy_root.top_cgroup
	// css: &(kmem_cache#29-o0 (struct freezer))->css, ss: &freezer_subsys, cgroup_dummy_top: &cgroup_dummy_root.top_cgroup
	init_css(css, ss, cgroup_dummy_top);

	// init_css(&root_task_group.css)에서 한일:
	// (&root_task_group.css)->cgroup: &cgroup_dummy_root.top_cgroup
	// (&root_task_group.css)->ss: &cpu_cgroup_subsys
	// (&root_task_group.css)->flags: 1

	// init_css(&root_cpuacct.css)에서 한일:
	// (&root_cpuacct.css)->cgroup: &cgroup_dummy_root.top_cgroup
	// (&root_cpuacct.css)->ss: &cpuacct_subsys
	// (&root_cpuacct.css)->flags: 1

	// init_css(kmem_cache#30-oX (struct cgroup_subsys_state))에서 한일:
	// (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(&(kmem_cache#29-o0 (struct freezer))->css)에서 한일:
	// (&(kmem_cache#29-o0 (struct freezer))->css)->cgroup: &cgroup_dummy_root.top_cgroup
	// (&(kmem_cache#29-o0 (struct freezer))->css)->ss: &freezer_subsys
	// (&(kmem_cache#29-o0 (struct freezer))->css)->flags: 1

	/* Update the init_css_set to contain a subsys
	 * pointer to this state - since the subsystem is
	 * newly registered, all tasks and hence the
	 * init_css_set is in the subsystem's top cgroup. */
	// ss->subsys_id: (&cpu_cgroup_subsys)->subsys_id: 1, css: &root_task_group.css
	// ss->subsys_id: (&cpuacct_subsys)->subsys_id: 2, css: &root_cpuacct.css
	// ss->subsys_id: (&cpuacct_subsys)->subsys_id: 0, css: kmem_cache#30-oX (struct cgroup_subsys_state)
	// ss->subsys_id: (&freezer_subsys)->subsys_id: 3, css: &(kmem_cache#29-o0 (struct freezer))->css
	init_css_set.subsys[ss->subsys_id] = css;
	// init_css_set.subsys[1]: &root_task_group.css
	// init_css_set.subsys[2]: &root_cpuacct.css
	// init_css_set.subsys[0]: kmem_cache#30-oX (struct cgroup_subsys_state)
	// init_css_set.subsys[3]: &(kmem_cache#29-o0 (struct freezer))->css

	// need_forkexit_callback: 0, ss->fork: (&cpu_cgroup_subsys)->fork: NULL, ss->exit: (&cpu_cgroup_subsys)->exit: cpu_cgroup_exit
	// need_forkexit_callback: 1, ss->fork: (&cpuacct_subsys)->fork: NULL, ss->exit: (&cpuacct_subsys)->exit: NULL
	// need_forkexit_callback: 1, ss->fork: (&debug_subsys)->fork: NULL, ss->exit: (&debug_subsys)->exit: NULL
	// need_forkexit_callback: 1, ss->fork: (&freezer_subsys)->fork: freezer_fork, ss->exit: (&freezer_subsys)->exit: NULL
	need_forkexit_callback |= ss->fork || ss->exit;
	// need_forkexit_callback: 1
	// need_forkexit_callback: 1
	// need_forkexit_callback: 1
	// need_forkexit_callback: 1

	/* At system boot, before all subsystems have been
	 * registered, no tasks have been forked, so we don't
	 * need to invoke fork callbacks here. */
	// list_empty(&init_task.tasks): 1
	// list_empty(&init_task.tasks): 1
	// list_empty(&init_task.tasks): 1
	// list_empty(&init_task.tasks): 1
	BUG_ON(!list_empty(&init_task.tasks));

	// css: &root_task_group.css, online_css(&root_task_group.css): 0
	// css: &root_cpuacct.css, online_css(&root_cpuacct.css): 0
	// css: kmem_cache#30-oX (struct cgroup_subsys_state), online_css(kmem_cache#30-oX (struct cgroup_subsys_state)): 0
	//
	// css: &(kmem_cache#29-o0 (struct freezer))->css, online_css(&(kmem_cache#29-o0 (struct freezer))->css): 0
	BUG_ON(online_css(css));

online_css()

  • call: start_kernel()
  • cgroup_init()
  • call: cgroup_init()
  • bdi_init()
  • for_each_buildtin_subsys()
    • cgroup_init_subsys(ss): ss=cgroup_subsys
  • call: cgroup_init_subsys(): ss: &debug_subsys
  • call: cgroup_init_subsys(): ss: &freezer_subsys
  • printk()
  • mutex_lock(&cgroup_mutex)
  • cgroup_init_cftsets(ss); // ss: &freezer_subsys
  • list_add(&ss->sibling, &cgroup_dummy_root.subsys_list);
  • css = ss->css_alloc(cgroup_css(cgroup_dummy_top, ss));
  • BUG_ON(IS_ERR(css));
  • init_css(css, ss, cgroup_dummy_top);
  • !list_empty(&init_task.tasks)
  • online_css(css)
  • call: online_css()
// ARM10C 20160716
// css: &(kmem_cache#29-o0 (struct freezer))->css
static int online_css(struct cgroup_subsys_state *css)
{
	// css->ss: (&root_task_group.css)->ss: &cpu_cgroup_subsys
	// css->ss: (&root_cpuacct.css)->ss: &cpuacct_subsys
	// css->ss: (kmem_cache#30-oX (struct cgroup_subsys_state))->ss: &debug_subsys
	// css->ss: (&(kmem_cache#29-o0 (struct freezer))->css)->ss: &freezer_subsys
	struct cgroup_subsys *ss = css->ss;
	// ss: &cpu_cgroup_subsys
	// ss: &cpuacct_subsys
	// ss: &debug_subsys
	// ss: &freezer_subsys

	int ret = 0;
	// ret: 0
	// ret: 0
	// ret: 0
	// ret: 0

	lockdep_assert_held(&cgroup_mutex); // null function

// 2016/07/16 종료

	// ss->css_online: (&cpu_cgroup_subsys)->css_online: cpu_cgroup_css_online
	// ss->css_online: (&cpuacct_subsys)->css_online: NULL
	// ss->css_online: (&debug_subsys)->css_online: NULL
	// ss->css_online: (&freezer_subsys)->css_online: freezer_css_online
	if (ss->css_online)
		// ss->css_online: (&cpu_cgroup_subsys)->css_online: cpu_cgroup_css_online,
		// css: &root_task_group.css
		// cpu_cgroup_css_online(&root_task_group.css): 0
		//
		// ss->css_online: (&freezer_subsys)->css_online: freezer_css_online,
		// css: &(kmem_cache#29-o0 (struct freezer))->css
		// freezer_css_online(&(kmem_cache#29-o0 (struct freezer))->css): 0
		ret = ss->css_online(css);
		// ret: 0

css_online()

  • call: start_kernel()
  • cgroup_init()
  • call: cgroup_init()
  • bdi_init()
  • for_each_buildtin_subsys()
    • cgroup_init_subsys(ss): ss=cgroup_subsys
  • call: cgroup_init_subsys(): ss: &debug_subsys
  • call: cgroup_init_subsys(): ss: &freezer_subsys
  • printk()
  • mutex_lock(&cgroup_mutex)
  • cgroup_init_cftsets(ss); // ss: &freezer_subsys
  • list_add(&ss->sibling, &cgroup_dummy_root.subsys_list);
  • css = ss->css_alloc(cgroup_css(cgroup_dummy_top, ss));
  • BUG_ON(IS_ERR(css));
  • init_css(css, ss, cgroup_dummy_top);
  • !list_empty(&init_task.tasks)
  • online_css(css)
  • call: css_online()

log

da0eb1e..6caa0f4  master     -> origin/master
Updating da0eb1e..6caa0f4
Fast-forward
include/linux/cgroup.h           |   8 ++
include/linux/kernel.h           |   1 +
include/linux/lockdep.h          |   3 +
include/linux/mutex.h            |  18 +++++
include/linux/rcupdate.h         |   2 +
include/linux/spinlock.h         |  12 ++-
include/linux/spinlock_api_smp.h |   3 +
kernel/cgroup.c                  | 163 +++++++++++++++++++++++++++++++++------
kernel/cgroup_freezer.c          |  46 ++++++++++-
kernel/locking/spinlock.c        |   2 +
10 files changed, 233 insertions(+), 25 deletions(-)