10차 ARM 리눅스 커널 스터디 50주차(2014.04.12) 후기입니다.
일시 : 2014.04.12 (50주차)
모임명 : NAVER개발자커뮤니티지원_IAMROOT.ORG_10차ARM-C
장소 : 토즈 타워점
장소지원 : NAVER 개발자 커뮤니티 지원 프로그램
참여인원 : 4명
스터디 진도 :
- start_kernel()-> mm_init()->mem_init()->free_all_bootmem() 까지
- 지난 스터디에 이어서 mem_init()을 계속 분석합니다.
free_all_bootmem()
- 리눅스 커널의 메모리 할당자 (buddy system)으로 전환하는 과정입니다. 버디 시스템 이전에 사용했던 메모리를 회수합니다. bddata는 커널이 이전 초기화 과정에서 사용했던 모든 메모리의 사용 여부를 나타냅니다. 이 메모리를 회수하는 과정이 free_all_bootmem()함수입니다.
- list_for_each_entry(bdata, &bdata_list, list) 메모리 자료 구조 bdata의 엔트리에서 free_all_bootmem_core(bdata)를 실행하여 total_pages 를 구합니다.
- total_pages 총 free된 page 수 + 0x6
free_all_bootmem_core(bdata)
- 인자로 전달 받은 메모리 자료 구조 bdata에서 미사용 영역(free)에 해당하는 page를 미사용영역으로 설정하는 과정입니다.
- while (start < end)
- start : 0x20000
- end : 0x4f800
- NORMAL 영역을 반복적으로 돌면서 bdata->node_bootmem_map을 참조하여 2가지로 구분하여 미사용 영역을 설정합니다.
- if (IS_ALIGNED(start, BITS_PER_LONG) && vec == ~0UL)
- 여기서 order가 5인 것과 order가 0인 것의 처리를 나누어서 처리합니다.
order가 5 인 경우
- BITS_PER_LONG : 32이며 이것은 buddy order 5에 해당합니다.
- 즉 32비트에 해당하는 page frame을 구하여 미사용 영역을 설정합니다.
- __free_pages_bootmem(pfn_to_page(start), order)를 order는 5로 해서 실행
- free_pages_ok(page,order)를 실행
order가 5 가 아닌 경우
- BITS_PER_LOG : 32만큼 반복해서 order를 0부터 시작해서 해당하는 page frame을 구하여 미사용 영역으로 설정합니다.
- order를 늘려가며 buudy에 해당하는 영역을 합해서 order에 해당하는 미사용 영역을 설정합니다.
- __free_pages_bootmem(page, 0)를 order는 0로 해서 실행
- free_hot_cold_page(page,0)을 실행
__free_pages_bootmem()
- CPU0의 vm_event_states.event[PGFREE] 를 order로 설정함
- page에 해당하는 pageblock의 migrate flag를 반환함
- struct page의 index 멤버에 migratetype을 저장함
- order 값의 buddy를 contig_page_data에 추가함
- &contig_page_data->node_zones[ZONE_NORMAL].vm_stat[NR_FREE_PAGES]: 2^order 값으로 설정
- vmstat.c의 vm_stat[NR_FREE_PAGES] 전역 변수에도 2^order 로 설정
- 현재 page의 page->private값과 buddy의 page->private값이 같으면 page order를 합치는 작업 수행
total_pages : 총 free된 page 수 + 0x6
- 0x6을 더하는 이유?
- bootmap_pages에 해당하는 크기가 0x6이며 이를 회수했기 때문에 0x6을 더합니다.
pcp list에서 lru를 붙이거나 제거하는 의미
- pcp list에 page->lru를 붙인다는 것은 가장 최근에 수정된 page와 연결된 pcp list의 위치의 뒤에 붙여서 일종의 꼬리표처럼 됩니다. 즉 page->lru를 찾으면 가장 최근에 수정된 page의 위치를 알 수 있습니다. page->lru를 찾고 나서 page->lru를 지우면 최근에 수정된 page의 위치를 참조하는 것을 의미합니다.
if (!page_is_buddy(page, buddy, order))
- 여기에서 buddy를 비교하여 지금과 버디가 free라면 order를 증가해서 buddy를 합하는 과정을 실행합니다.
다음주 스터디 진도
- free_highpages()를 분석합니다.
git log
eb8631e..ff927bc master -> origin/master
Updating eb8631e..ff927bc
Fast-forward
arch/arm/include/asm/atomic.h | 2 +
arch/arm/include/asm/irqflags.h | 2 +
arch/arm/include/asm/spinlock.h | 1 +
arch/arm/mm/init.c | 2 +
include/asm-generic/atomic-long.h | 5 ++
include/asm-generic/percpu.h | 1 +
include/linux/cache.h | 5 +-
include/linux/compiler.h | 4 ++
include/linux/irqflags.h | 6 +-
include/linux/kernel.h | 1 +
include/linux/list.h | 7 +++
include/linux/lockdep.h | 1 +
include/linux/mm.h | 11 ++++
include/linux/mmzone.h | 6 +-
include/linux/page-isolation.h | 3 +-
include/linux/percpu.h | 80 ++++++++++++++++++++++++
include/linux/poison.h | 9 ++-
include/linux/preempt.h | 1 +
include/linux/spinlock.h | 3 +
include/linux/spinlock_api_smp.h | 2 +
include/linux/vmstat.h | 25 ++++++--
include/trace/events/kmem.h | 1 +
include/uapi/linux/kernel.h | 2 +
kernel/spinlock.c | 3 +-
lib/spinlock_debug.c | 2 +
mm/bootmem.c | 77 +++++++++++++++++++++++
mm/page_alloc.c | 298 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
mm/vmstat.c | 67 ++++++++++++++++++++
28 files changed, 579 insertions(+), 48 deletions(-)
댓글 없음:
댓글 쓰기