[커널 17차] 94주차

2022.06.19 00:51

ㅇㅇㅇ 조회 수:80

Reclaim 이론 스터디
- http://jake.dothome.co.kr/lru-lists-pagevecs/
- 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/


GFP flags
- 외부에서 실제로 요청할 때 사용하는 플래그

 

alloc flags
- 그냥 내부 변수로 생각됨

 

GFP_RECLAIMABLE
- 슬랩 캐시 생성시 reclaim/compaction 가능하도록 설정하는 플래그임

 

Workingset Detection : 2014년 처음 개발되서 file cache page에 적용되다가 v5.9에서 anon page에도 적용되었다
- anon page에 적용되면서 anon page들도 첫 fault 시 inactive list의 head에서 시작하는 것으로 보임

 

PTE.AF > 1 의 의미는?
- 여러 프로세스 또는 여러 테이블 또는 여러 가상 주소가 하나의 물리주소 페이지에 매핑된 경우, 이들의 AF들을 모두 합산한 결과
- 그렇다면 어떤 물리주소가 하나의 PTE로만 매핑되어 있으면 PTE.AF > 1이 될 수는 없다
- 이를 보완하기 위해 PG_referenced를 만들어서 이를 1로 만들어 다수 access하는 것을 탐지할 수 있게 한다

 

lazy free
- application이 MADV_FREE API를 통해서 이 영역 메모리는 이제 안쓸 것이라고 알려주면 굳이 swapping하지 않도록 PG_swapbacked 플래그를 클리어한다

 

pagevec
- lruvec의 pcpu 캐시
- lruvec에는 14개 이상의 page update를 batch를 반영하고 (lock overhead 때문)
- 대신 그보다 작은 update는 pagevec을 사용한다
- 함수 lru_add_drain_cpu()를 이용해서 pagevec 내용을 lruvec으로 반영할 수 있다


__alloc_pages_direct_reclaim()
- 인자로 gfp mask, order, alloc flags, alloc context ac를 받는다
- 출력으로 reclaim 진전이 있었는지 알려주는 did some progress를 인자로 출력하고 리턴값으로 reclaim으로 확보한 page를 리턴한다

 

- L4615 : 함수 __perform_reclaim()로 reclaim을 시도하고, reclaim에 진전이 없었으면 NULL을 리턴한다
- L4620 : 함수 get_page_from_freelist()로 메모리 할당을 시도한다
- L4627 : 메모리 할당이 실패하고 이것이 첫 번째 시도인 경우, 함수 unreserve_highatomic_pageblock()으로 high atomic pageblock reserve에서 요청된 migrate type으로 page를 steal하고 함수 drain_all_pages()를 이용해서 buddy pcplist에 있는 페이지들을 버디로 환원시킨다. 그 후 다시 함수 get_page_from_freelist()로 메모리 할당을 시도한다.
- L4634 : 할당된 페이지를 반환한다. 만약 두 번째 시도에서도 page 할당에 실패하면 NULL을 할당하게 된다

 

unreserve_highatomic_pageblock()
- 모든 zone에 대해서 루프를 돌면서 각 zone의 high atomic으로 reserve된 page 수가 pageblock 수인 512보다 큰 경우 alloc context의 migrate type으로 이동시킨다
- 만약 force 설정이 되면 high atomic page 수가 pageblock 수보다 작아도 강제로 이동시킨다

 

drain_all_pages()
- 모든 per-cpu pcplist 페이지들을 buddy 시스템으로 반환시킨다
- workqueue로 구현되어 느릴 수 있다
- work로는 함수 drain_local_pages_wq()가 사용된다

 

drain_local_pages_wq()
- 함수 drain_local_pages()를 이용해서 pcplist page들을 버디로 반환한다
- 함수 drain_local_pages()는 zone 설정 여부에 따라 drain_pages_zone(), drain_pages()를 호출하고 drain_pages()는 존 별로 drain_pages_zone()를 호출한다
- drain_pages_zone()은 free_pcppages_bulk()을 호출한다

 

free_pcppages_bulk()
- 인자로 zone, count, pcp를 받아서 pcplist에서 count만큼의 page를 버디로 반환한다
- pcplist에 있는 모든 page들은 동일한 zone, order를 가지고 있다고 가정한다
- pcplist에 대해 루프를 돌면서 모든 migrate type의 list의 page를 __free_one_page()를 이용, 모두 buddy로 반환한다

 

__perform_reclaim()
- 인자로 gfp mask, order, alloc context ac를 받는다

- L4586 : cond_resched() 호출로 더 우선순위 높은 task에 스케줄 양보
- L4589 : cpuset_memory_pressure_bump()로 per-cpuset reclaim 관련 stat 처리를 수행한다
- L4590 : CONFIG_PSI = n이므로 빈 함수
- L4591 : LOCKDEP 안하므로 빈 함수
- L4592 : 함수 memalloc_noreclaim_save()로 current->flags의 원본을 저장하고 PF_MEMALLOC을 set한다
- L4594 : 함수 try_to_free_pages()로 direct reclaim 시도하고 진척이 있는지 progress에 저장
- L4597 : 함수 memalloc_noreclaim_restore()로 원래의 current->flags를 복원한다
- L4598 ~ L4599 : CONFIG에 따라 빈 함수
- L4601 : cond_resched() 호출로 더 우선순위 높은 task에 스케줄 양보
- L4603 : reclaim progress를 리턴

 

try_to_free_pages()
- 인자로 zonelist, order, gfp mask, nodemask를 받는다

- L3601 : 지역변수 scan_control sc를 설정한다. 이는 reclaim 관련 설정이다. Reclaim할 페이지 수는 SWAP_CLUSTER_MAX = 32개로 설정하고, priority는 DEF_PRIORITY = 12, may_writepage는 !laptop_mode, may_unmap, may_swap은 둘 다 1로 설정한다. 나머지는 인자에 맞게 설정한다
- L3626 : throttle_direct_reclaim() 함수로 direct reclaim을 경우에 따라 throttle하고 fatal signal이 발생하면 1을 리턴하고 종료한다
- L3629 : current->reclaim_state를 sc.reclaim_state로 세팅한다
- L3630 : direct reclaim trace 시작
- L3632 : 함수 do_try_to_free_pages()로 direct reclaim을 시도하고 reclaim된 page 수를 nr_reclaimed로 받는다
- L3634 : direct reclaim trace 종료
- L3635 : current->reclaim_state를 NULL로 세팅한다
- L3637 : reclaim된 page 수를 리턴한다

 

throttle_direct_reclaim()
- 인자로 gfp mask, zonelist, nodemask를 받는다
- Storage가 network를 사용하면서 PFMEMALLOC reserve가 얼마 남지 않으면 direct reclaim을 throttle 시킨다. 그동안 kswapd가 동작하여 low watermark 수준으로 올라오면 process를 다시 wake 시킨다. 그 동안 fatal signal이 전달되면 true를 리턴한고 아니면 false를 리턴한다

- L3531 : current->flags가 PF_KTHREAD이면, 즉 현재 task가 커널 task이면 throttle 하지 않고 false 리턴한다
- L3538 : current task에 대해 fatal signal이 pending되어 있으면 throttle 하지 않고 false 리턴한다 (빨리 죽어야 함)
- L3555 : zone에 대해서 루프를 돌면서 다음을 수행한다
- L3557 : 현재 zone index가 ZONE_NORMAL보다 높으면 다음 zone으로 continue
- L3561 : 아니면 현재 zone의 node pgdat을 구한다
- L3562 : 현재 node가 direct reclaim이 가능한지 함수 allow_direct_reclaim()으로 판정하고 가능하면 false 리턴한다
- L3564 : 소속 node가 direct reclaim이 불가능하고 index가 ZONE_NORMAL보다 같거나 낮은 zone을 찾으면 break하여 루프를 중단한다
- L3568 : 모든 node의 zone index가 ZONE_NORMAL보다 높으면 false 리턴
- L3572 : PGSCAN_DIRECT_THROTTLE stat을 account한다
- L3582 : gfp_mask에 __GFP_FS가 설정되어 있지 않은 경우, 파일 시스템 락을 현재 프로세스가 잡고 있을 수도 있기 때문에 이 경우 kswapd가 blocking될 수 있음. 따라서 kswapd를 믿고 wait할 수 없으므로 일정 시간 동안 wait하고 continue한다
- L3587 : __GFP_FS 설정되어 있는 경우엔 kswapd가 깨워 줄 때까지 그냥 wait한다
- L3590 : wake up 후 process에 fatal signal이 전달된 경우에는 true 리턴
- L3594 : 아니면 false 리턴한다

 

allow_direct_reclaim()
- 인자로 pgdat을 받는다
- L3476 : 현 노드에서 kswapd 실패 횟수가 MAX_RECLAIM_RETRIES보다 같거나 크면 direct reclaim이 필요하므로 true 리턴
- L3479 : ZONE_DMA부터 ZONE_NORMAL까지 현 노드의 zone에 대해 루프를 돈다
- L3481 : 현 zone이 managed_zone이 아니면 다음 zone으로 continue
- L3484 : 현 zone이 reclaimable page가 없으면 다음 zone으로 continue
- L3487 : local 변수 pfmemalloc_reserve에 현 zone의 min watermark page를 누적한다
- L3488 : local 변수 free_pages에 현 zone의 free page 수를 누적한다
- L3492 : pfmemalloc_reserve = 0이면, 즉 reserve가 없으면 true 리턴한다 (reclaim 필요)
- L3495 : free_pages 수가 pfmemalloc_reserve 절반 보다 크면 wmark_ok를 참으로 설정
- L3498 : wmark_ok가 아니고 kswapd가 wait이면 kswapd의 highest zone index를 NORMAL로 바꾸고 kswapd를 꺠운다
- L3505 : wmark_ok를 리턴한다

 

zone_reclaimable_pages()
- 인자로 zone을 받아 active file, inactive file 및 active anon, inactive anon page 수 합계를 리턴한다
- 이 때 anon page를 reclaim 할 수 있는 경우에만 (swap 공간이 있을 때만) active anon, inactive anon page 수를 합산한다

번호 제목 글쓴이 날짜 조회 수
공지 [공지] 스터디 정리 노트 공간입니다. woos 2016.05.14 626
146 [커널 17차] 101~102주차 ㅇㅇㅇ 2022.08.21 47
145 [커널 18차] 65주차 kkr 2022.08.20 27
144 [커널 18차] 64주차 kkr 2022.08.13 75
143 [커널 17차] 100주차 [1] ㅇㅇㅇ 2022.08.06 98
142 [커널 18차] 63주차 kkr 2022.08.06 102
141 [커널 17차] 99주차 ㅇㅇㅇ 2022.07.31 35
140 [커널 18차] 62주차 kkr 2022.07.30 26
139 [커널 17차] 97~98주차 ㅇㅇㅇ 2022.07.24 52
138 [커널 18차] 61주차 kkr 2022.07.23 113
137 [커널 18차] 60주차 kkr 2022.07.16 129
136 [커널 17차] 95~96주차 ㅇㅇㅇ 2022.07.10 105
135 [커널 18차] 59주차 kkr 2022.07.09 126
134 [커널 19차] 8주차 kanlee 2022.07.02 160
133 [커널 19차] 7주차 kanlee 2022.07.02 95
132 [커널 19차] 6주차 kanlee 2022.07.02 42
131 [커널 19차] 5주차 kanlee 2022.07.02 38
130 [커널 19차] 4주차 kanlee 2022.07.02 106
129 [커널 18차] 57주차 kkr 2022.06.25 129
» [커널 17차] 94주차 ㅇㅇㅇ 2022.06.19 80
127 [커널 18차] 56주차 kkr 2022.06.18 71
XE Login