============
cgroup 초기화 분석을 마치고, 2주간 각자 휴식을 쉬했습니다. 다시 리눅스 커널을 분석합니다.
-
9월 5일 진도로 다시 복습을 했습니다.
-
setup_per_cpu_pageset();
- // per cpu가 사용하는 pageset의 각각의 zone 맴버값 초기화 수행
- numa_policy_init(); // null function
- // late_time_init: NULL
- sched_clock_init();
- // sched_clock_running 값을 1 로 초기화 수행
- calibrate_delay();
- // BogoMIPS값을 결정하기위한 계산을 수행하고 결과를 출력함
- pidmap_init();
- // pidmap 을 사용하기 위한 초기화 수행
-
이후 새로운 소스 코드를 계속 분석했습니다.
-
anon_vma_init();
- anon vma 를 사용하기 위한 kmem_cache 할당자 초기화 수행
- thread_info_cache_init();
- null function
- cred_init();
- credentials 를 사용하기 위한 kmem_cache 할당자 초기화 수행
- fork_init(totalram_pages);
- totalram_pages: 총 free된 page 수
- task_struct 를 사용하기 위한 kmem_cache 할당자 초기화 수행
- max_threads값을 계산하여 init_task에 threads값의 limit 값 설정함
// ARM10C 20130824
// asmlinkage의 의미
// http://www.spinics.net/lists/arm-kernel/msg87677.html
asmlinkage void __init start_kernel(void)
{
char * command_line;
extern const struct kernel_param __start___param[], __stop___param[];
// ATAG,DTB 정보로 사용
...
// 2015/08/08 시작
page_cgroup_init(); // null function
debug_objects_mem_init(); // null function
kmemleak_init(); // null function
// 2015/08/22 종료
// 2015/09/12 시작
setup_per_cpu_pageset();
// per cpu가 사용하는 pageset의 각각의 zone 맴버값 초기화 수행
numa_policy_init(); // null function
// late_time_init: NULL
if (late_otime_init)
late_time_init();
sched_clock_init();
// sched_clock_running 값을 1 로 초기화 수행
calibrate_delay();
// BogoMIPS값을 결정하기위한 계산을 수행하고 결과를 출력함
pidmap_init();
// pidmap 을 사용하기 위한 초기화 수행
// 2015/09/12 종료
// 2015/09/19 시작
anon_vma_init();
- call: start_kernel()
- anon_vma_init()
// ARM10C 20150919
void __init anon_vma_init(void)
{
// sizeof(struct anon_vma): 40 bytes, SLAB_DESTROY_BY_RCU: 0x00080000UL, SLAB_PANIC: 0x00040000UL
// kmem_cache_create("anon_vma", 40, 0, 0x000C0000, anon_vma_ctor): kmem_cache#18
anon_vma_cachep = kmem_cache_create("anon_vma", sizeof(struct anon_vma),
0, SLAB_DESTROY_BY_RCU|SLAB_PANIC, anon_vma_ctor);
// anon_vma_cachep: kmem_cache#18
// SLAB_PANIC: 0x00040000UL
// KMEM_CACHE(anon_vma_chain, 0x00040000):
// kmem_cache_create("anon_vma_chain", sizeof(struct anon_vma_chain), __alignof__(struct anon_vma_chain), (0x00040000), NULL): kmem_cache#17
anon_vma_chain_cachep = KMEM_CACHE(anon_vma_chain, SLAB_PANIC);
// anon_vma_chain_cachep: kmem_cache#17
}
- anon_vma_cachep 할당
- sizeof(struct anon_vma): 40Byte
- #define SLAB_DESTROY_BY_RCU 0x00080000UL /* Defer freeing slabs to RCU */
- #define SLAB_PANIC 0x00040000UL /* Panic if kmem_cache_create() fails */
- kmem_cache_create()
- "anon_vma", sizeof(struct anon_vma): 40Byte, 0, 0x000C0000, anon_vma_ctor
- kmem_cache_crate()에 의해서 #18번이 새로 할당된다.
- 참조로 #22 번에서 많으 것을 할당하였고, 이번(#18)에 anon_vma_cache를 할당한다.
- #21: idr_layer_cache
- #20: radix_tree_node
- #19: pid
- #18: anon_vma_cache
kmem_cache_create(const char *name, size_t size, size_t align,
unsigned long flags, void (*ctor)(void *))
{
o // name: "anon_vma", size: 40, align: 0, flags: 0x000C0000, ctor: anon_vma_ctor
// kmem_cache_create_memcg(NULL, "anon_vma", 40, 0, 0x000C0000, anon_vma_ctor): kmem_cache#18
return kmem_cache_create_memcg(NULL, name, size, align, flags, ctor, NULL);
// return kmem_cache#18
}
EXPORT_SYMBOL(kmem_cache_create);
- anon_vma_chain_cachep 할당
- struct list_head anon_vma_chain; /* Serialized by mmap_sem & page_table_lock
- #define SLAB_PANIC 0x00040000UL /* Panic if kmem_cache_create() fails */
- KMEM_CACHE(anon_vma_chain, 0x00040000):
// kmem_cache_create("anon_vma_chain", sizeof(struct anon_vma_chain), __alignof__(struct anon_vma_chain), (0x00040000), NULL)
#define KMEM_CACHE(__struct, __flags) kmem_cache_create(#__struct,\
sizeof(struct __struct), __alignof__(struct __struct),\
(__flags), NULL)
- name: "anon_vma_chain", size: 32, align: 4, flags: 0x00040000, ctor: NULL
- kmem_cache_create_memcg(NULL, "anon_vma_chain", 32, 4, 0x00040000, NULL): kmem_cache#17 b - return kmem_cache#17
kmem_cache_create(const char *name, size_t size, size_t align,
unsigned long flags, void (*ctor)(void *))
{
// "anon_vma_chain", sizeof(struct anon_vma_chain): 32Byte, 4, 0x00040000, NULL
return kmem_cache_create_memcg(NULL, name, size, align, flags, ctor, NULL);
// return kmem_cache#17
}
EXPORT_SYMBOL(kmem_cache_create);
- anon_vma_init() 정리
- anon_vma를 사용하기 위한 kmem_cache#18을 할당했다.
- anon_vma_chain을 사용하기 위한 kmem_cache#18을 할당했다.
// ARM10C 20130824
asmlinkage void __init start_kernel(void)
{
char * command_line;
extern const struct kernel_param __start___param[], __stop___param[];
// ATAG,DTB 정보로 사용
...
// 2015/09/19 시작
anon_vma_init();
#ifdef CONFIG_X86 // CONFIG_X86=n
if (efi_enabled(EFI_RUNTIME_SERVICES))
efi_enter_virtual_mode();
#endif
thread_info_cache_init();
- call: start_kernel()
- thread_info_cache_init()
# if THREAD_SIZE >= PAGE_SIZE
void __init __weak thread_info_cache_init(void)
{
}
- THREAD_SIZE 8192 (0x2000)
- PAGE_SIZE 4096 (0x1000)
- 여기서 __weak인데
- THREAD_SIZE: 8192 >= PAGE_SIZE : 4096 이므로 weak로 가서 NULL Function이다.
- 아래 선언된 부분은 THREAD_SIZE가 PAGE_SIZE보다 작은 경우에
- 메모리를 kmem_cache로 할당 받는 것을 말한다.
- 우리 분석 시스템에서는 적용하지 않는다.
- 따라서 null function이다.
// ARM10C 20130824
asmlinkage void __init start_kernel(void)
{
char * command_line;
extern const struct kernel_param __start___param[], __stop___param[];
// ATAG,DTB 정보로 사용
...
// 2015/09/19 시작
anon_vma_init();
#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();
- call: start_kernel()
- cred_init()
- credentials - 인증에 사용되는 프로세스의 식별자를 말함.
- sizeof(struct cred): 92Byte
struct cred {
atomic_t usage;
#ifdef CONFIG_DEBUG_CREDENTIALS
atomic_t subscribers; /* number of processes subscribed */
void *put_addr;
unsigned magic;
#define CRED_MAGIC 0x43736564
#define CRED_MAGIC_DEAD 0x44656144
#endif
kuid_t uid; /* real UID of the task */
kgid_t gid; /* real GID of the task */
kuid_t suid; /* saved UID of the task */
kgid_t sgid; /* saved GID of the task */
kuid_t euid; /* effective UID of the task */
kgid_t egid; /* effective GID of the task */
kuid_t fsuid; /* UID for VFS ops */
kgid_t fsgid; /* GID for VFS ops */
unsigned securebits; /* SUID-less security management */
kernel_cap_t cap_inheritable; /* caps our children can inherit */
kernel_cap_t cap_permitted; /* caps we're permitted */
kernel_cap_t cap_effective; /* caps we can actually use */
kernel_cap_t cap_bset; /* capability bounding set */
#ifdef CONFIG_KEYS
unsigned char jit_keyring; /* default keyring to attach requested
* keys to */
struct key __rcu *session_keyring; /* keyring inherited over fork */
struct key *process_keyring; /* keyring private to this process */
struct key *thread_keyring; /* keyring private to this thread */
struct key *request_key_auth; /* assumed request_key authority */
#endif
#ifdef CONFIG_SECURITY
void *security; /* subjective LSM security */
#endif
struct user_struct *user; /* real user ID subscription */
struct user_namespace *user_ns; /* user_ns the caps and keyrings are relative to. */
struct group_info *group_info; /* supplementary groups for euid/fsgid */
struct rcu_head rcu; /* RCU deletion hook */
};
// ARM10C 20150919
void __init cred_init(void)
{
/* allocate a slab in which we can store credentials */
// sizeof(struct cred): 92 bytes, SLAB_HWCACHE_ALIGN: 0x00002000UL, SLAB_PANIC: 0x00040000UL
// kmem_cache_create("cred_jar", 92, 0, 0x00042000, NULL): kmem_cache#16
cred_jar = kmem_cache_create("cred_jar", sizeof(struct cred),
0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
// cred_jar: kmem_cache#16
}
kmem_cache_create(const char *name, size_t size, size_t align,
unsigned long flags, void (*ctor)(void *))
{
o // name: "anon_vma", size: 40, align: 0, flags: 0x000C0000, ctor: anon_vma_ctor
// kmem_cache_create_memcg(NULL, "anon_vma", 40, 0, 0x000C0000, anon_vma_ctor): kmem_cache#18
return kmem_cache_create_memcg(NULL, name, size, align, flags, ctor, NULL);
// return kmem_cache#18
}
EXPORT_SYMBOL(kmem_cache_create);
- cred_jar: kmem_cache_create() // name: "cred_jar", size: 92, align: 0, flags: 0x00042000, ctor: NULL // kmem_cache_create_memcg(NULL, "cred_jar", 92, 0, 0x00042000, NULL): kmem_cache#16
- kmem_cache_create()
- "anon_vma", sizeof(struct anon_vma): 40Byte, 0, 0x000C0000, anon_vma_ctor
- kmem_cache_crate()에 의해서 #18번이 새로 할당된다.
- 참조로 #22 번에서 많으 것을 할당하였고, 이번(#16)에 cred_jar를 할당한다.
- #21: idr_layer_cache
- #20: radix_tree_node
- #19: pid
- #18: anon_vma
- #17: anon_vma_chain
- #16: cred_jar
- cred_init() 정리
- cred_jar를 사용하기 위한 kmem_cache#16을 할당했다.
// ARM10C 20130824
asmlinkage void __init start_kernel(void)
{
char * command_line;
extern const struct kernel_param __start___param[], __stop___param[];
// ATAG,DTB 정보로 사용
...
// 2015/09/19 시작
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);
- call: start_kernel()
- fork_init()
- totalram_pages: 총 free된 page수
- totalram_pages
- // totalram_pages: 총 free된 page 수+ 0x6 + 1
- free_all_bootmem() : 총 free된 page 수 + 0x6
- free_high_mem(): 총 free된 page 수 + 0x6 +1
unsigned long totalram_pages __read_mostly;
// ARM10C 20150919
// totalram_pages: 총 free된 page 수
void __init fork_init(unsigned long mempages)
{
#ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR // CONFIG_ARCH_TASK_STRUCT_ALLOCATOR=n
#ifndef ARCH_MIN_TASKALIGN
// L1_CACHE_BYTES: 64
// ARCH_MIN_TASKALIGN: 64
#define ARCH_MIN_TASKALIGN L1_CACHE_BYTES
#endif
/* create a slab on which task_structs can be allocated */
// FIXME:
// sizeof(struct task_struct) 계산 필요, 임시로 XXX bytes로 명명함
// ARCH_MIN_TASKALIGN: 64, SLAB_PANIC: 0x00040000UL, SLAB_NOTRACK: 0x00000000UL, sizeof(struct task_struct): XXX
// kmem_cache_create("task_struct", XXX, 64, 0x00040000, NULL): kmem_cache#15
task_struct_cachep =
kmem_cache_create("task_struct", sizeof(struct task_struct),
ARCH_MIN_TASKALIGN, SLAB_PANIC | SLAB_NOTRACK, NULL);
// task_struct_cachep: kmem_cache#15
#endif
- kmem_cache_create()
- task_struct_cachep
- kmem_cache_create()
- "task_struct", sizeof(struct task_struct),
- ARCH_MIN_TASKALIGN: 64, SLAB_PANIC | SLAB_NOTRACK : 0x0040000, NULL);
// ARM10C 20150919
// "task_struct", sizeof(struct task_struct): XXX, 64, 0x00040000, NULL
struct kmem_cache *
kmem_cache_create(const char *name, size_t size, size_t align,
unsigned long flags, void (*ctor)(void *))
{
// name: "task_struct", size: XXX, align: 64, flags: 0x00040000, ctor: NULL
// kmem_cache_create_memcg(NULL, "task_struct", XXX, 64, 0x00040000, NULL): kmem_cache#15
return kmem_cache_create_memcg(NULL, name, size, align, flags, ctor, NULL);
// return kmem_cache#15
}
- 이번(#15)에 task_struct_cachep를 할당한다.
- #21: idr_layer_cache
- #20: radix_tree_node
- #19: pid
- #18: anon_vma
- #17: anon_vma_chain
- #16: cred_jar
- #15: task_struct_cachep
// ARM10C 20150919
// totalram_pages: 총 free된 page 수
void __init fork_init(unsigned long mempages)
{
#ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR // CONFIG_ARCH_TASK_STRUCT_ALLOCATOR=n
#ifndef ARCH_MIN_TASKALIGN
// L1_CACHE_BYTES: 64
// ARCH_MIN_TASKALIGN: 64
#define ARCH_MIN_TASKALIGN L1_CACHE_BYTES
#endif
/* create a slab on which task_structs can be allocated */
// FIXME:
// sizeof(struct task_struct) 계산 필요, 임시로 XXX bytes로 명명함
// ARCH_MIN_TASKALIGN: 64, SLAB_PANIC: 0x00040000UL, SLAB_NOTRACK: 0x00000000UL, sizeof(struct task_struct): XXX
// kmem_cache_create("task_struct", XXX, 64, 0x00040000, NULL): kmem_cache#15
task_struct_cachep =
kmem_cache_create("task_struct", sizeof(struct task_struct),
ARCH_MIN_TASKALIGN, SLAB_PANIC | SLAB_NOTRACK, NULL);
// task_struct_cachep: kmem_cache#15
#endif
/* do the arch specific task caches init */
arch_task_cache_init(); // null function
/*
* The default maximum number of threads is set to a safe
* value: the thread structures can take up at most half
* of memory.
*/
// mempages: 총 free된 page 수, THREAD_SIZE: 0x2000, PAGE_SIZE: 0x1000
max_threads = mempages / (8 * THREAD_SIZE / PAGE_SIZE);
// max_threads: 총 free된 page 수 / 16
/*
* we need to allow at least 20 threads to boot a system
*/
// max_threads: 총 free된 page 수 / 16
if (max_threads < 20)
max_threads = 20;
// max_threads: 총 free된 page 수 / 16, RLIMIT_NPROC: 6
init_task.signal->rlim[RLIMIT_NPROC].rlim_cur = max_threads/2;
// init_task.signal->rlim[6].rlim_cur: 총 free된 page 수 / 32
// max_threads: 총 free된 page 수 / 16, RLIMIT_NPROC: 6
init_task.signal->rlim[RLIMIT_NPROC].rlim_max = max_threads/2;
// init_task.signal->rlim[6].rlim_max: 총 free된 page 수 / 32
// RLIMIT_SIGPENDING: 11
init_task.signal->rlim[RLIMIT_SIGPENDING] =
init_task.signal->rlim[RLIMIT_NPROC];
// init_task.signal->rlim[11].rlim_cur: 총 free된 page 수 / 32
// init_task.signal->rlim[11].rlim_max: 총 free된 page 수 / 32
}
- THREAD_SIZE: 0x2000, PAGE_SIZE: 0x1000
- max_threads : 총 free된 page 수 / 16
- 최소는 20개 이상
- RLIMIT_NPROC
# define RLIMIT_NPROC 6 /* max number of processes */
- init_task `
// ARM10C 20130831
// .cpus_allowed : 3
// ARM10C 20140315
// ARM10C 20140510
// PF_KTHREAD: 0x00200000
// MAX_PRIO: 140
// SCHED_NORMAL: 0
// ARM10C 20150808
// ATOMIC_INIT(2): { (2) }
// PF_KTHREAD: 0x00200000
// MAX_PRIO: 140
// SCHED_NORMAL: 0
// CPU_MASK_ALL: (cpumask_t) { { [0] = 0xf } }
// NR_CPUS: 4
// LIST_HEAD_INIT(init_task.se.group_node):
// { &(init_task.se.group_node), &(init_task.se.group_node) }
// LIST_HEAD_INIT(init_task.rt.run_list):
// { &(init_task.rt.run_list), &(init_task.rt.run_list) }
// RR_TIMESLICE: 10
// LIST_HEAD_INIT(init_task.tasks):
// { &(init_task.tasks), &(init_task.tasks) }
// INIT_PUSHABLE_TASKS(init_task):
// .pushable_tasks =
// {
// .prio = (140),
// .prio_list = { &((init_task.pushable_tasks).prio_list), &((init_task.pushable_tasks).prio_list) },
// .node_list = { &((init_task.pushable_tasks).node_list), &((init_task.pushable_tasks).node_list) },
// },
// INIT_CGROUP_SCHED(init_task):
// .sched_task_group = &root_task_group,
// LIST_HEAD_INIT(init_task.ptraced):
// { &(init_task.ptraced), &(init_task.ptraced) }
// LIST_HEAD_INIT(init_task.ptrace_entry):
// { &(init_task.ptrace_entry), &(init_task.ptrace_entry) }
// LIST_HEAD_INIT(init_task.children):
// { &(init_task.children), &(init_task.children) }
// LIST_HEAD_INIT(init_task.sibling):
// { &(init_task.sibling), &(init_task.sibling) }
// RCU_POINTER_INITIALIZER(real_cred, &init_cred):
// .real_cred = (typeof(*&init_cred) __force __rcu *)(&init_cred)
// RCU_POINTER_INITIALIZER(cred, &init_cred):
// .cred = (typeof(*&init_cred) __force __rcu *)(&init_cred)
// INIT_TASK_COMM: "swapper"
// INIT_THREAD: {}
// LIST_HEAD_INIT(init_task.pending.list):
// { &(init_task.pending.list), &(init_task.pending.list) }
// __SPIN_LOCK_UNLOCKED(init_task.alloc_lock):
// (spinlock_t )
// { { .rlock =
// {
// .raw_lock = { { 0 } },
// .magic = 0xdead4ead,
// .owner_cpu = -1,
// .owner = 0xffffffff,
// }
// } }
// INIT_CPU_TIMERS(init_task.cpu_timers):
// {
// { &(init_task.cpu_timers[0]), &(init_task.cpu_timers[0]) },
// { &(init_task.cpu_timers[1]), &(init_task.cpu_timers[1]) },
// { &(init_task.cpu_timers[2]), &(init_task.cpu_timers[2]) },
// }
// __RAW_SPIN_LOCK_UNLOCKED(init_task.pi_lock):
// (raw_spinlock_t)
// {
// .raw_lock = { { 0 } },
// .magic = 0xdead4ead,
// .owner_cpu = -1,
// .owner = 0xffffffff,
// }
// PIDTYPE_PID: 0
// PIDTYPE_PGID: 1
// PIDTYPE_SID: 2
// INIT_PID_LINK(PIDTYPE_PID):
// {
// .node = {
// .next = NULL,
// .pprev = NULL,
// },
// .pid = &init_struct_pid,
// }
// INIT_PID_LINK(PIDTYPE_PGID):
// {
// .node = {
// .next = NULL,
// .pprev = NULL,
// },
// .pid = &init_struct_pid,
// }
// INIT_PID_LINK(PIDTYPE_SID):
// {
// .node = {
// .next = NULL,
// .pprev = NULL,
// },
// .pid = &init_struct_pid,
// }
// LIST_HEAD_INIT(init_task.thread_group):
// { &(init_task.thread_group), &(init_task.thread_group) }
// INIT_TRACE_RECURSION: .trace_recursion = 0,
// INIT_TASK_RCU_PREEMPT(init_task):
// .rcu_read_lock_nesting = 0,
// .rcu_read_unlock_special = 0,
// .rcu_node_entry = { &(init_task.rcu_node_entry), &(init_task.rcu_node_entry) },
// .rcu_blocked_node = NULL,
//
// #define INIT_TASK(init_task):
// {
// .state = 0,
// .stack = &init_thread_info,
// .usage = { (2) },
// .flags = 0x00200000,
// .prio = 120,
// .static_prio = 120,
// .normal_prio = 120,
// .policy = 0,
// .cpus_allowed = (cpumask_t) { { [0] = 0xf } },
// .nr_cpus_allowed = 4,
// .mm = NULL,
// .active_mm = &init_mm,
// .se = {
// .group_node = { &(init_task.se.group_node), &(init_task.se.group_node) }
// },
// .rt = {
// .run_list = { &(init_task.rt.run_list), &(init_task.rt.run_list) },
// .time_slice = 10,
// },
// .tasks = { &(init_task.tasks), &(init_task.tasks) },
// .pushable_tasks =
// {
// .prio = (140),
// .prio_list = { &((init_task.pushable_tasks).prio_list), &((init_task.pushable_tasks).prio_list) },
// .node_list = { &((init_task.pushable_tasks).node_list), &((init_task.pushable_tasks).node_list) },
// },
// .sched_task_group = &root_task_group,
// .ptraced = { &(init_task.ptraced), &(init_task.ptraced) },
// .ptrace_entry = { &(init_task.ptrace_entry), &(init_task.ptrace_entry) },
// .real_parent = &init_task,
// .parent = &init_task,
// .children = { &(init_task.children), &(init_task.children) },
// .sibling = { &(init_task.sibling), &(init_task.sibling) },
// .group_leader = &init_task,
// .real_cred = (typeof(*&init_cred) __force __rcu *)(&init_cred),
// .cred = (typeof(*&init_cred) __force __rcu *)(&init_cred),
// .comm = "swapper",
// .thread = {},
// .fs = &init_fs,
// .files = &init_files,
// .signal = &init_signals,
// .sighand = &init_sighand,
// .nsproxy = &init_nsproxy,
// .pending = {
// .list = { &(init_task.pending.list), &(init_task.pending.list) },
// .signal = {{0}}
// },
// .blocked = {{0}},
// .alloc_lock =
// (spinlock_t )
// { { .rlock =
// {
// .raw_lock = { { 0 } },
// .magic = 0xdead4ead,
// .owner_cpu = -1,
// .owner = 0xffffffff,
// }
// } },
// .journal_info = NULL,
// .cpu_timers =
// {
// { &(init_task.cpu_timers[0]), &(init_task.cpu_timers[0]) },
// { &(init_task.cpu_timers[1]), &(init_task.cpu_timers[1]) },
// { &(init_task.cpu_timers[2]), &(init_task.cpu_timers[2]) },
// },
// .pi_lock =
// (raw_spinlock_t)
// {
// .raw_lock = { { 0 } },
// .magic = 0xdead4ead,
// .owner_cpu = -1,
// .owner = 0xffffffff,
// },
// .timer_slack_ns = 50000,
// .pids = {
// [0] =
// {
// .node = {
// .next = NULL,
// .pprev = NULL,
// },
// .pid = &init_struct_pid,
// },
// [1] =
// {
// .node = {
// .next = NULL,
// .pprev = NULL,
// },
// .pid = &init_struct_pid,
// },
// [2] =
// {
// .node = {
// .next = NULL,
// .pprev = NULL,
// },
// .pid = &init_struct_pid,
// },
// },
// .thread_group = { &(init_task.thread_group), &(init_task.thread_group) },
// .trace_recursion = 0,
// .rcu_read_lock_nesting = 0,
// .rcu_read_unlock_special = 0,
// .rcu_node_entry = { &(init_task.rcu_node_entry), &(init_task.rcu_node_entry) },
// .rcu_blocked_node = NULL,
// }
#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
- init_task.signal->rlim[RLIMIT_NPROC].rlim_cur = max_threads/2;
- init_task.signal->rlim[RLIMIT_NPROC: 6 ].rlim_cur : 총 free된 page수 /2
- init_task.signal->rlim[RLIMIT_NPROC].rlim_max = max_threads/2;
- init_task.signal->rlim[RLIMIT_NPROC: 6 ].rlim_max : 총 free된 page수 /2
- init_task.signal->rlim[RLIMIT_SIGPENDING] = init_task.signal->rlim[RLIMIT_NPROC];
- init_task.signal->rlim[RLIMIT_SIGPENDING: 11 ] =
- init_task.signal->rlim[RLIMIT_NPROC: 6];
- fork_init(totalram_pages);에서 한일
- task_struct를 사용하기 위한 kmem_cache 할당
- max_threads 계산하여 init_task 에 threads 값의 limit 값을 설정.
// ARM10C 20130824
asmlinkage void __init start_kernel(void)
{
char * command_line;
extern const struct kernel_param __start___param[], __stop___param[];
...
// 2015/09/19 시작
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();
- start_kernel()
- fork_init()
- proc_caches_init()
// ARM10C 20150919
void __init proc_caches_init(void)
{
// sizeof(struct sighand_struct): 1324 bytes, 0xc2000
// kmem_cache_create("sighand_cache", 1324, 0, 0xc2000, sighand_ctor): kmem_cache#14
sighand_cachep = kmem_cache_create("sighand_cache",
sizeof(struct sighand_struct), 0,
SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_DESTROY_BY_RCU|
SLAB_NOTRACK, sighand_ctor);
// sighand_cachep: kmem_cache#14
signal_cachep = kmem_cache_create("signal_cache",
sizeof(struct signal_struct), 0,
SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL);
files_cachep = kmem_cache_create("files_cache",
sizeof(struct files_struct), 0,
SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL);
fs_cachep = kmem_cache_create("fs_cache",
sizeof(struct fs_struct), 0,
SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL);
/*
* FIXME! The "sizeof(struct mm_struct)" currently includes the
* whole struct cpumask for the OFFSTACK case. We could change
* this to *only* allocate as much of it as required by the
* maximum number of CPU's we can ever have. The cpumask_allocation
* is at the end of the structure, exactly for that reason.
*/
mm_cachep = kmem_cache_create("mm_struct",
sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN,
SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL);
vm_area_cachep = KMEM_CACHE(vm_area_struct, SLAB_PANIC);
mmap_init();
// mmap_init에서 한일:
// (&(&(&(&vm_committed_as)->lock)->wait_lock)->rlock)->raw_lock: { { 0 } }
// (&(&(&(&vm_committed_as)->lock)->wait_lock)->rlock)->magic: 0xdead4ead
// (&(&(&(&vm_committed_as)->lock)->wait_lock)->rlock)->owner: 0xffffffff
// (&(&(&(&vm_committed_as)->lock)->wait_lock)->rlock)->owner_cpu: 0xffffffff
// (&(&vm_committed_as)->list)->next: &(&vm_committed_as)->list
// (&(&vm_committed_as)->list)->prev: &(&vm_committed_as)->list
// (&vm_committed_as)->count: 0
// (&vm_committed_as)->counters: kmem_cache#26-o0 에서 할당된 4 bytes 메모리 주소
// list head 인 &percpu_counters에 &(&vm_committed_as)->list를 연결함
// 2015/09/19 종료
nsproxy_cache_init();
}
struct sighand_struct {
atomic_t count;
struct k_sigaction action[_NSIG];
spinlock_t siglock;
wait_queue_head_t signalfd_wqh;
};
struct k_sigaction {
struct sigaction sa;
#ifdef __ARCH_HAS_KA_RESTORER
__sigrestore_t ka_restorer;
#endif
};
struct sigaction {
union {
__sighandler_t _sa_handler;
void (*_sa_sigaction)(int, struct siginfo *, void *);
} _u;
sigset_t sa_mask;
unsigned long sa_flags;
void (*sa_restorer)(void);
};
- __signalfn_t
typedef __signalfn_t __user *__sighandler_t;
- struct siginfo
typedef struct siginfo {
int si_signo;
int si_errno;
int si_code;
union {
int _pad[SI_PAD_SIZE];
/* kill() */
struct {
__kernel_pid_t _pid; /* sender's pid */
__ARCH_SI_UID_T _uid; /* sender's uid */
} _kill;
/* POSIX.1b timers */
struct {
__kernel_timer_t _tid; /* timer id */
int _overrun; /* overrun count */
char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)];
sigval_t _sigval; /* same as below */
int _sys_private; /* not to be passed to user */
} _timer;
/* POSIX.1b signals */
struct {
__kernel_pid_t _pid; /* sender's pid */
__ARCH_SI_UID_T _uid; /* sender's uid */
sigval_t _sigval;
} _rt;
/* SIGCHLD */
struct {
__kernel_pid_t _pid; /* which child */
__ARCH_SI_UID_T _uid; /* sender's uid */
int _status; /* exit code */
__ARCH_SI_CLOCK_T _utime;
__ARCH_SI_CLOCK_T _stime;
} _sigchld;
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
struct {
void __user *_addr; /* faulting insn/memory ref. */
#ifdef __ARCH_SI_TRAPNO
int _trapno; /* TRAP # which caused the signal */
#endif
short _addr_lsb; /* LSB of the reported address */
} _sigfault;
/* SIGPOLL */
struct {
__ARCH_SI_BAND_T _band; /* POLL_IN, POLL_OUT, POLL_MSG */
int _fd;
} _sigpoll;
/* SIGSYS */
struct {
void __user *_call_addr; /* calling user insn */
int _syscall; /* triggering system call number */
unsigned int _arch; /* AUDIT_ARCH_* of syscall */
} _sigsys;
} _sifields;
} __ARCH_SI_ATTRIBUTES siginfo_t;
- sighand_cachep: kmem_cache_create()
- "sighand_cache", sizeof(struct sighand_struct), 0,
- SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_DESTROY_BY_RCU|
- SLAB_NOTRACK, sighand_ctor);
- kmem_cache#14: sighand_cachep
- signal_cachep: kmem_cache_create()
- "signal_cache",sizeof(struct signal_struct), 0,
- SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL);
- files_cachep: kmem_cache_create(
- "files_cache", sizeof(struct files_struct), 0,
- SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL);
- fs_cachep: kmem_cache_create(
- "fs_cache", sizeof(struct fs_struct), 0,
- SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL);
- mm_cachep: kmem_cache_create(
- "mm_struct", sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN,
- SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL);
- vm_area_cachep = KMEM_CACHE(vm_area_struct, SLAB_PANIC);
void __init proc_caches_init(void)
{
...
mmap_init();
nsproxy_cache_init();
}
- mmap_init();
- call: start_kernel()
- proc_cache_init()
- mmap_init()
// ARM10C 20150919
void __init mmap_init(void)
{
int ret;
// percpu_counter_init(&vm_committed_as, 0): 0
ret = percpu_counter_init(&vm_committed_as, 0);
// ret: 0
// percpu_counter_init에서 한일:
// (&(&(&(&vm_committed_as)->lock)->wait_lock)->rlock)->raw_lock: { { 0 } }
// (&(&(&(&vm_committed_as)->lock)->wait_lock)->rlock)->magic: 0xdead4ead
// (&(&(&(&vm_committed_as)->lock)->wait_lock)->rlock)->owner: 0xffffffff
// (&(&(&(&vm_committed_as)->lock)->wait_lock)->rlock)->owner_cpu: 0xffffffff
// (&(&vm_committed_as)->list)->next: &(&vm_committed_as)->list
// (&(&vm_committed_as)->list)->prev: &(&vm_committed_as)->list
// (&vm_committed_as)->count: 0
// (&vm_committed_as)->counters: kmem_cache#26-o0 에서 할당된 4 bytes 메모리 주소
// list head 인 &percpu_counters에 &(&vm_committed_as)->list를 연결함
// ret: 0
VM_BUG_ON(ret);
}
- start_kernel()
- proc_cache_init()
- mmap_init()
- percpu_counter_init()
- mmap_init()
// ARM10C 20150919
// &vm_committed_as, 0
#define percpu_counter_init(fbc, value) \
({ \
static struct lock_class_key __key; \
\
__percpu_counter_init(fbc, value, &__key); \
})
- start_kernel()
- proc_cache_init()
- mmap_init()
- percpu_counter_init()
- __percpu_counter_init()
- percpu_counter_init()
- mmap_init()
// ARM10C 20150919
// &vm_committed_as, 0, &__key
int __percpu_counter_init(struct percpu_counter *fbc, s64 amount,
struct lock_class_key *key)
{
// &fbc->lock: &(&vm_committed_as)->lock
raw_spin_lock_init(&fbc->lock);
// raw_spin_lock_init에서 한일:
// (&(&(&(&vm_committed_as)->lock)->wait_lock)->rlock)->raw_lock: { { 0 } }
// (&(&(&(&vm_committed_as)->lock)->wait_lock)->rlock)->magic: 0xdead4ead
// (&(&(&(&vm_committed_as)->lock)->wait_lock)->rlock)->owner: 0xffffffff
// (&(&(&(&vm_committed_as)->lock)->wait_lock)->rlock)->owner_cpu: 0xffffffff
// &fbc->lock: &(&vm_committed_as)->lock, key: &__key
lockdep_set_class(&fbc->lock, key); // null function
// fbc->count: (&vm_committed_as)->count, amount: 0
fbc->count = amount;
// fbc->count: (&vm_committed_as)->count: 0
// fbc->counters: (&vm_committed_as)->counters,
// alloc_percpu(s32): kmem_cache#26-o0 에서 할당된 4 bytes 메모리 주소
fbc->counters = alloc_percpu(s32);
// fbc->counters: (&vm_committed_as)->counters: kmem_cache#26-o0 에서 할당된 4 bytes 메모리 주소
// fbc->counters: (&vm_committed_as)->counters: kmem_cache#26-o0 에서 할당된 4 bytes 메모리 주소
if (!fbc->counters)
return -ENOMEM;
// fbc: &vm_committed_as
debug_percpu_counter_activate(fbc); // null function
#ifdef CONFIG_HOTPLUG_CPU // CONFIG_HOTPLUG_CPU=y
// &fbc->list: &(&vm_committed_as)->list
INIT_LIST_HEAD(&fbc->list);
// INIT_LIST_HEAD에서 한일:
// (&(&vm_committed_as)->list)->next: &(&vm_committed_as)->list
// (&(&vm_committed_as)->list)->prev: &(&vm_committed_as)->list
spin_lock(&percpu_counters_lock);
// spin_lock에서 한일:
// &percpu_counters_lock을 사용한 spin lock 수행
// &fbc->list: &(&vm_committed_as)->list
list_add(&fbc->list, &percpu_counters);
// list_add에서 한일:
// list head 인 &percpu_counters에 &(&vm_committed_as)->list를 연결함
spin_unlock(&percpu_counters_lock);
// spin_lock에서 한일:
// &percpu_counters_lock을 사용한 spin unlock 수행
#endif
return 0;
}
EXPORT_SYMBOL(__percpu_counter_init);
- alloc_percpu(s32)
- kmem_cache@26-o0 에서 할당된 4Byte 메모리 주소.
#define alloc_percpu(type) \
(typeof(type) __percpu *)__alloc_percpu(sizeof(type), __alignof__(type))
- debug_percpu_counter_activate(fbc);
- // null function
- INIT_LIST_HEAD(&fbc->list);
- &fbc->list: &(&(vm_committed_as)->list
-
spin_lock(&percpu_counters_lock);
-
list_add(&fbc->list, &percpu_counters);
-
spin_unlock(&percpu_counters_lock);
-
nsproxy_cache_init();
int __init nsproxy_cache_init(void)
{
nsproxy_cachep = KMEM_CACHE(nsproxy, SLAB_PANIC);
return 0;
}
- 1st log
18884c1..bd5956f master -> origin/master
Updating 18884c1..bd5956f
Fast-forward
arch/arm/include/asm/page.h | 1 +
arch/arm/include/asm/thread_info.h | 4 ++++
include/linux/capability.h | 5 +++++
include/linux/cred.h | 8 +++++---
include/linux/rbtree.h | 2 ++
include/linux/rmap.h | 9 +++++++--
include/linux/rwsem-spinlock.h | 4 +++-
include/linux/rwsem.h | 2 +-
include/linux/slab.h | 6 ++++++
include/linux/slub_def.h | 1 +
include/linux/spinlock_types.h | 1 +
include/linux/types.h | 3 +++
include/linux/uidgid.h | 4 +++-
include/uapi/asm-generic/posix_types.h | 1 +
include/uapi/linux/capability.h | 2 ++
init/main.c | 12 +++++++++---
kernel/cred.c | 5 +++++
kernel/fork.c | 4 ++--
mm/rmap.c | 12 ++++++++++++
mm/slab_common.c | 21 +++++++++++++++++++++
20 files changed, 94 insertions(+), 13 deletions(-)
- 2nd log
bd5956f..a53fe59 master -> origin/master
Updating bd5956f..a53fe59
Fast-forward
arch/arm/include/asm/cache.h | 1 +
arch/arm/include/asm/signal.h | 11 +++++++++++
arch/arm/include/uapi/asm/signal.h | 2 ++
include/linux/list.h | 5 +++++
include/linux/lockdep.h | 1 +
include/linux/percpu.h | 2 ++
include/linux/percpu_counter.h | 9 +++++++--
include/linux/sched.h | 17 +++++++++++------
include/linux/signal.h | 4 +++-
include/linux/slab.h | 1 +
include/linux/spinlock.h | 5 +++++
include/linux/spinlock_types.h | 2 ++
include/linux/wait.h | 1 +
include/uapi/asm-generic/resource.h | 4 ++++
include/uapi/asm-generic/signal-defs.h | 1 +
init/main.c | 4 ++++
kernel/fork.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++---
kernel/locking/spinlock_debug.c | 2 ++
lib/percpu_counter.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
mm/mmap.c | 17 +++++++++++++++++
mm/page_alloc.c | 1 +
mm/percpu.c | 2 ++
mm/slab_common.c | 24 +++++++++++++++++++-----
23 files changed, 212 insertions(+), 22 deletions(-)