Transcript 슬라이드 1
init/main.c 1. top_cpuset.cpus_allowed에 cpuset mask만큼의 메모리 할당. 2. 전역변수 cpuset_mems_generation 1 증가. cpuset_init_early 3. Top_cpuset.mems_generation에 대입. alloc_bootmem_cpumask_var(&top_cpuset.cpus_allowd) 1. Cpumask_size를 얻어옴. 2. Cpumask size가 차지하는 비트맵크기 계산하여 할당. Top_cpuset.mems_generation = cpuset_mems_generation++ Cpuset_mems_generation Cpuset 이 서로다른 태스크에 있을때 cpuset.memsgeneration이 락 필요없이 업데이트되고 태 스크의 cpuset_mems_generation 에서만 락 획득후 업데 이트하는 시나리오를 위한 전역변수. -- TODO 추후 내용이나 이해하기쉬운형태로 추가 필요. init/main.c page_cgroup_init 1. Mem_cgoup_subsys.disabled의 값을 참조해서 disable 이면 return. 2. Online 되어있는 모든 노드들에 대해서 각 노드의 nr_pages를 구해서 nr_pages만큼의 page_cgroup의 메 모리를 할당받아서 초기화. for_each_online_node Allac_node_page_croup(nid) 온라인 되어있는 모든 노드들에 대해서 각 노드의 nr_pages를 구해서 nr_pages만큼의 page_cgroup의 메모리를 할당받아서 초기화시킴. 만약 메모리를 할당하지 못하였다면 fail로 점프하고 kernel panic 발생. init/main.c 1. Mem_map에서 free area를 마킹하고 free memory가 얼 마인지 알려줌. 2. 각 노드의 뱅크를 순회하면서 뱅크사이의 홀에 대한 영 역을 free해줌. 3. Bitmap의 bit가 0으로 셋팅된 page를 Buddy Allocator 로 릴리즈 함. 4. 시스템의 가용 메모리와 코드, 데이터사이즈등 정보표시. mem_init pfn_to_page(max_pfn + PHYS_PFN_OFFSET) – mem_map for_each_online_node Free_unused_memmap_node(node, &meminfo) Totalram_page += free_all_bootmem_node(pgdat) Mem_map이 차지하는 page구조체의 개수를 구함. 현재 노드의 뱅크를 순회하여 뱅크사이에 사용되지 않은 메모리영역(hole)을 기술하는 페이지 구조체영역이 사 용 가능하도록 free해줌. Node의 free page를 buddy allocator에 release시킴. 1. pglist_data를 가지고 있는 페이지의 상태를 pgdat>node_id, NODE_INFO로 셋팅. 2. 각 zone의 wait_table이 있다면 해당하는 hash_table의 엔트리를 포함하고 있는 페이지들에 대해서 페이지의 속성을 NODE_INFO로 세팅한다. 3. 섹션 정보를 페이지에 세팅해줌. 4. 현재 노드의 free가능한 page를 free시킴. 1) 일반 page인 경우는 free할 위치부터 bulk(order를 기준으로)free할수 있으면 gree하고 bulk로 free할 수 없는 경우는 한 page씩 free시킴. 2) metadata를 가지고 있는 page인 경우, 즉 bitmap이 나 frame 정보등. 이 경우는 meta data를 가지고 있는 page를 구하여 해제시킴. 5. Page들이 해제될때 buddy system이 관여되어 해당 정 보가 기록됨. 6. 총 free된 page의 수를 리턴. init/main.c::mem_init() CONFIG_HIGHMEM for_each_online_node Highmem page를 free시킨다. 참조할부분 : arch/arm/mm/mmu.c::sanity_check_meminfo() 자세한 메커니즘 TODO. 아직 파악안됨. for_each_nodebank Totalhigh_page += free_area(start, end, NULL) 1. Bank 별 physical size 정보 표시. 2. Code size, data size, init size를 구한 후 정보 프린트. 3. Overcommit 정책 설정. Sysctl_overcommit_memory Memory overcommit 정책을 OVERCOMMIT_ALWAYS 로 설정한다. -- Overcomit에 관하여 자세한 것은 TODO. init/main.c Enable_debug_pagealloc() CONFIG_DEBUG_PAGEALLOC Debug_pagealloc_enabled = 1; init/main.c Cpu_hotplug_init() CONFIG_SMP Cpu Hotplug 변수 초기화. init/main.c Kmem_cache_init() Kmem_list3_init(&initkmem_list3[i]); Set_up_list3s(&cache_cache, CACHE_CACHE); 1. Cache_cache 초기화 2. Kmalloc에서 사용할 기본 사이즈별 캐시 생성 3. 정적으로 생성해놓은 per cpu cache를 슬랩할당자로 다 시 만듬 4. Per cpu cache 를 리사이징해서 다시 생성 5. -- TODO slab할당자와 kmem_cache_init 함수에대한 대 대적인 보충 수정 요약 정리 작업이 필요. 1. Cache_cache 초기화. 2. Online상태 cachep->nodelist[node]에 kmem_list3[index+node]를 할당. Cache가 shrink, growing 해야 할 주기를 설정해줌. Cache_cache를 cache_chain에 추가. Colour_off에 cacheline 크기를 설정. cache_cache.array[0]가 initarray_cache.cache를 가리키도록 해준다. array_cache는 per cpu data인 cpu별 캐시이다. 슬랩오브젝트 할당,해제시 바로 슬랩할당자 에게 요청하는게 아니라 이 자료구조에 먼저 접근해서 처리를 시도한다. cache가 관리하는 오브젝트의 크기를 계산하여 캐시라인크기에 맞춰서 정렬하여 buffer_size 멤버에 세팅한다. 그리고 캐시에서의 슬랩오브젝트 index를 빠르게 구하기 위해 뉴튼랩슨법 으로 구한 값을 eciprocal_buffer_size에 세팅한다. order를 지수승??으로 갖는 페이지 크기를 구해 해당 캐시의 오브젝트를 할당할 수 있는지를 검사한다. 그리고 해당 order에서 할당가능한 오브젝트의 갯수(cache_cache.num에 세팅됨), 할당하고 남은 공간(leftover)을 구한다. 0에서 MAX_ORDER -1까지 이 작업을 반복하여 최소 order값을 구한다. init/main.c Kmem_cache_init() 1. kmalloc에서 사용할 기본 할당 크기값을 갖는 구조체의 배열인 malloc_sizes, cache_name 을 sizes, names에 세팅한다. 2. INDEX_AC 매크로는 arraycache_init 구조체 캐시를 생성하는데 알맞은 크기를 가지고 있 는 malloc_sizes[] 배열의 인덱스를 리턴한다. 3. 캐시를 생성한 다음 위 매크로가 리턴한 인덱스로 접근한 sizes[].cs_cachep이 가리키게 한 다. INDEX_L3 매크로도 INDEX_AC매크로와 동일한 방법으로 kmem_list3 구조체 캐시에 대한 인덱스를 리턴하는데 두 매크로가 리턴한 인덱스가 동일하지 않다면 kmem_list3 에 대한 캐 시를 생성하여 cs_cachep가 가리키게 한다. 4. 마지막으로 sizes배열을 순회하여 캐시를 생성하지 않은 사이즈에 대한 캐시를 생성해준다. 정적으로 생성해놓은 per cpu cache를 슬랩할당자로 다시 만듬. 컴파일 타임에 생성된 array_cache인 initarray_cache, initarray_generic 캐시를 슬랩할당자를 이용해서 다시 할당한다. 역시 컴파일 타임에 생성된 kmem_list3를 사용하는 cache_cache, malloc_size[INDEX_AC], malloc_sizes[INDEX_L3]의 nodelist를 새롭게 생성한 kmem_list3로 교체해준다. per cpu cache를 리사이징해서 다시 생성 cache_chain에 연결된 모든 캐시들을 순회하며 per cpu cache의 limit, share등의 멤버를 새롭게 세팅해준다. 마지막으로 register_cpu_notifier()를 호출하여 cpu의 상태가 변경시에 cpuup_callback()이 호출되로록 설정해준다. init/main.c Kmemtrace_init() 하는 일 없음. Debug_objects_mem_init() Idr_init_cache() IDR은 radix tree의 일종으로 정수 ID와 특정한 포인터 값을 연결시키는 역할을 해 준다. 원래는 POSIX timer 관련 시스템 콜 구현을 위해 작성된 것으로 특정한 timer 객체를 다룰 수 있는 ID를 생성해 주는 역할을 하였으나 현재는 각종 장치 드라이버나 VFS 레이어에서도 널리 사용된다. idr_layer_cache 캐시를 생성함 Setup_per_cpu_pageset() Process_zones(smp_processor_id()) Register_cpu_notifire(&pageset_notifire) 시스템의 모든 존의 pageset[cpu] 변수에 메모리를 할당하고 멤버를 적절한 값으로 세팅한다. Callback 등록.