2014년 4월 15일 화요일

[Linux Kernel] 50주차(2014.04.12) 후기

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

댓글 없음:

댓글 쓰기