[커널 17차] 92~93주차

2022.06.11 22:22

ㅇㅇㅇ 조회 수:93

92주차 : 휴식

 

Direct reclaim
- 현재 context에서 바로 reclaim하는 것 (sync reclaim)

 

Reclaim과 compaction 모두 우선 순위가 높으면 sync 낮으면 async이다

 

__alloc_pages_slowpath()
- 입력으로 gfp mask, order, alloc context ac를 받는다

 

- L4875 : can_direct_reclaim = gfp_mask & __GFP_DIRECT_RECLAIM
- L4876 : costly_order = order > PAGE_ALLOC_COSTLY_ORDER
- L4891 : gfp_mask에 __GFP_ATOMIC과 __GFP_DIRECT_RECLAIM이 모두 있으면 경고하고 __GFP_ATOMIC를 제거한다

 

- L4895 : retry_cpuset - cpuset mems_allowed가 변경되면 점프하는 위치

- L4896 : compaction_retries, no_progress_loops를 0으로 리셋
- L4898 : compact_priority를 DEF_COMPACT_PRIORITY로 리셋 (default setting)
- L4899 : cpuset_mems_cookie를 함수 read_mems_allowed_begin()로 현재 current task의 mems_allowed_seq를 받아온다. 이 번호가 바뀌면 mems_allowed가 바뀌었다는 의미이다
- L4906 : 함수 gfp_to_alloc_flags()을 이용, gfp mask로부터 제대로 된 alloc flags를 가져온다
- L4914 : alloc context ac로부터 preferred_zoneref를 받아온다
- L4916 : preferred zoneref가 NULL이면 nopage로 이동
- L4919 : alloc_flags에 ALLOC_KSWAPD가 있으면 wake_all_kswapds()로 kswapd를 깨운다
- L4926 : 함수 get_page_from_freelist()로 page를 할당받고 성공하면 got_pg로 이동한다
- L4939 : direct reclaim이 가능하고, pfmemalloc이 아니면서 costly order이거나 order >= 1 이면서 unmovable이면 if문으로 진입
- L4943 : 함수 __alloc_pages_direct_compact()으로 가장 낮은 우선 순위 INIT_COMPACT_PRIORITY로 compaction을 시도한다 (async)
- L4947 : compaction 결과 page가 할당되었으면 got_pg로 이동한다
- L4954 : costly_order이고 gfp_mask에 __GFP_NORETRY가 있으면 if 문 진입
- L4972 : compact_result가 COMPACT_SKIPPED 이거나 COMPACT_DEFERRED 이면 nopage로 이동한다
- L4981 : compact_priority에 INIT_COMPACT_PRIORITY를 할당한다

 

- L4985 : retry
- L4987 : alloc_flags에 ALLOC_KSWAPD가 있으면 wake_all_kswapds()로 kswapd를 깨운다. 중간에 sleep할 수도 있기 때문에 retry 시마다 다시 깨운다
- L4990 : gfp mask에 따라 reserve pool을 사용해도 되는 요청인 경우 alloc_flags를 ALLOC_NO_WATERMARKS 또는 ALLOC_OOM으로 업데이트하고 movable migrate인 경우에는 ALLOC_CMA도 추가한다
- L4999 : alloc flags가 ALLOC_CPUSET이 아니거나 reserve pool을 사용해도 되는 요청이면 nodemask와 preferred zoneref를 리셋한다
- L5006 : 함수 get_page_from_freelist()로 다시 메모리 할당을 시도하고, 성공하면 got_pg로 이동한다

- L5011 : direct reclaim을 할 수 없는 요청인 경우 nopage로 이동
- L5015 : current->flags가 PF_MEMALLOC이면 nopage로 이동. 이 두 경우는 direct reclaim하기 어려운 케이스이다

- L5019 : 함수 __alloc_pages_direct_reclaim()로 direct reclaim 시도하고 성공하면 got_pg로 이동
- L5025 : 함수 __alloc_pages_direct_compact()로 compaction 시도하고 성공하면 got_pg로 이동

- L5031 : gfp mask가 __GFP_NORETRY이면 nopage로 이동
- L5038 : costly_order이거나 gfp_mask가 __GFP_RETRY_MAYFAIL이 아니면 nopage로 이동

- L5041 : 함수 should_reclaim_retry()로 reclaim을 재시도해야하는지 판단하고 그렇다면 retry로 이동
- 5051 : reclaim 시도에 progress가 있었고 함수 should_compact_retry()가 참이면 retry로 이동

- L5059 : 함수 check_retry_cpuset()로 cpuset이 바뀌는 경우가 발생했는지 체크하고 그렇다면 retry_cpuset으로 이동

- L5063 : 함수 __alloc_pages_may_oom()로 process killing을 시도하고 page 할당이 성공했으면 got_pg로 이동
- 5068 : oom victim이 자기 자신이면서 alloc flags가 ALLOC_OOM 이거나 gfp_mask가 __GFP_NOMEMALLOC이면 nopage로 이동

- L5074 : oom killer가 진전이 있었으면 no_progress_loops = 0으로 하고 retry로 이동

 

- L5079 : nopage

- L5081 : 함수 check_retry_cpuset()로 cpuset이 바뀌는 경우가 발생했는지 체크하고 그렇다면 retry_cpuset으로 이동
- L5088 : gfp mask에 __GFP_NOFAIL가 있으면 if 문 진입
- L5093 : direct reclaim이 불가능하면 fail로 이동
- L5101 : current->flags가 PF_MEMALLOC이면 경고
- L5109 : order > PAGE_ALLOC_COSTLY_ORDER이면 경고
- L5117 : 함수 __alloc_pages_cpuset_fallback()로 처음엔 ALLOC_HARDER | ALLOC_CPUSET로 get_page_from_freelist() 시도하고 안되면 ALLOC_HARDER로 get_page_from_freelist() 시도, 성공하면 got_pg로 이동
- L5121 : 실패하면 cond_resched() 실행 후 retry로 이동

 

- L5124 : fail
- L5125 : page 할당 실패 경고


- L5127 : got_pg
- L5128 : 할당된 page 리턴

 

====================================

 

Reclaim 이론
- https://lpc.events/event/11/contributions/896/attachments/793/1493/slides-r2.pdf
- https://biriukov.dev/docs/page-cache/4-page-cache-eviction-and-page-reclaim/
- http://jake.dothome.co.kr/lru-lists-pagevecs/

 

Compaction
- https://lwn.net/Articles/368869/
- https://lwn.net/Articles/817905/
- https://woodz.tistory.com/42
- http://jake.dothome.co.kr/zonned-allocator-compaction/

XE Login