[커널 17차] 72주차

2022.01.16 22:57

ㅇㅇㅇ 조회 수:90

free_low_memory_core_early()
- for_each_free_mem_range() 매크로 부터 계속 진행
- 각 memblock memory 영역 중 reserved 영역이 아닌 region에 대해서 루프를 돌면서
- 함수 __free_memory_core()를 수행하고 free 된 pfn 수를 합하여 리턴한다

 

 __free_memory_core()
- start pfn과 end pfn을 받아서 함수 __free_pages_memory()를 수행하여 페이지 free 작업을 수행하고
- end pfn - start pfn을 리턴한다

 

__free_pages_memory()
- start pfn과 end pfn을 받는다
- start pfn의 ffs를 계산해서 page 수의 align을 구하고 이를 order로 잡는다
- 예를 들어 start pfn이 192면 alignment가 64이므로 2^6 —> 6이 order가 된다
- start pfn +  2^6 > end pfn 이면 end pfn 보다 작아질 때까지 order를 감소시킨다
- 함수 memblock_free_pages()에 order를 이용하여 free 작업을 수행한다
- start pfn에 2^6을 더한 후 start pfn이 end pfn보다 커질 때까지 위 작업을 반복한다

 

memblock_free_pages()
- __free_pages_core() 함수 호출

 

__free_pages_core()
- 페이지를 order 만큼 루프를 돌면서 __ClearPageReserved()를 수행하고 함수 set_page_count()로 _refcount를 0으로 만든다
- 이 때 함수 prefetchw()를 이용하여 prefetch를 수행한다
- page의 managed_pages에 처리한 page 수를 더한다
- 함수 __free_pages_ok() 호출 <— 진행 중

 

__free_pages_ok()
- 함수 free_pages_prepare() 호출 <— 진행 중

 

free_pages_prepare()
- 인자로 page 구조체 포인터, order, check free bool 변수, fpi_t (free page info) 플래그를 받는다
- 함수 should_skip_kasan_poison()로 fpi_t 플래그로부터 kasan 및 poison을 skip하는지 체크한다
- page가 compound page인데 tail page이면 버그를 발생시킨다
- page order가 0이고 hwpoison이면 false 리턴하여 본 페이지를 buddy memory로 반환 불가능함을 알려준다. 또한 Cgroup 및 page owner 처리도 수행한다
- Page order가 0이 아닌 경우, 함수 PageCompound()로 page의 compound page 여부를 구한다
- Page가 compound page이면서 page flag 상의 compound order와 함수 인자로 받은 order가 다르면 버그를 발생시킨다
- Compound page인 경우 page flag의 double map 및 hwpoisoned flag를 clear한다
- 루프를 돌면서 order의 두 번째 페이지부터 마지막 페이지에 대해 다음을 수행한다
1) Compound page의 경우 함수 free_tail_pages_check()로 compound page 데이터에 대한 체크를 수행하고 compound page 데이터를 클리어한다
2) 함수 check_free_page()로 free 시 체크해야 하는 page 데이터와 플래그를 체크한다
3) hwposion을 제외한 page flag를 모두 클리어한다
- Page mapping이 남아 있으면 클리어한다
- Control group 관련 데이터를 클리어한다 (uncharge 수행)
- check free 인자가 true이면 함수 check_free_page()로 현재 page를 체크한다
- 위의 sanity check에서 오류가 있으면 false를 리턴한다 <— 여기까지 진행

 

free_tail_pages_check()
- 인자로 head page와 tail page를 받아서 compound page의 sanity를 체크하고, mapping과 compound head를 삭제한다
- Sanity check는 compound map count, TAIL_MAPPING, page tail flag, head page data check로 이루어진다
- 또한 상수 LIST_POISON1에 대해서 LSB가 1이 아님을 체크하는 코드도 포함된다. 이는 상수값이 올바른지 빌드 타임에 체크하는 것이다

 

check_free_page()
- map count가 -1이 아니거나, mapping이 NULL이 아니거나, refcount가 0이 아니거나 page free 시에 체크해야 하는 flag들이 NULL이 아니면 에러를 리턴한다

 

Page owner
- 각 페이지를 누가 페이지를 할당했는지 추적하는 기능
- 메모리 누수 등 디버깅에 사용됨
- 페이지 할당이 발생하면 호출 스택 및 페이지의 order 등 각종 할당 정보가 페이지의 특정 장소에 저장된다
- https://www.kernelmsg.com/6

 

PAGE ALLOCATION
- https://www.kernel.org/doc/gorman/html/understand/understand009.html

 

HW POISON
- https://www.kernel.org/doc/html/latest/vm/hwpoison.html
- https://lwn.net/Articles/348886/

 

COMPOUND PAGES
- https://lwn.net/Articles/619514/
- http://jake.dothome.co.kr/compound/

 

Anonymous pages
- https://yongshikmoon.github.io/2021/04/18/anon_pages.html
- https://stackoverflow.com/questions/13024087/what-are-memory-mapped-page-and-anonymous-page
- https://www.kernel.org/doc/html/latest/admin-guide/mm/concepts.html

XE Login