[커널 17차] 104주차

2022.09.04 18:46

ㅇㅇㅇ 조회 수:87

page_referenced_one()
- 인자로 page, vma, address, arg를 받는다
- L776 : 구조체 page_vma_mapped_walk pvmw에 인자로 받은 page, vma, address를 복사한다
- L781 : 로컬 변수 referenced = 0으로 초기화
- L783 : 함수 page_vma_mapped_walk()로 page에 매핑되는 page table entry (pmd, pte)를 반복 검색한다
- L784 : 함수 내에서 업데이트된 address를 가져온다
- L786 : vma->vm_flags가 VM_LOCKED이면 함수 page_vma_mapped_walk_done()로 pmd table page의 lock을 풀고, arg->vm_flags에 VM_LOCKED을 달아주고 false를 리턴한다
- L792 : pvmw.pte를 찾은 경우 함수 ptep_clear_flush_young_notify()로 pte의 AF 플래그를 클리어하고, 원래 set되어 있었으면 vma->vm_flags가 VM_SEQ_READ가 아닌 경우 referenced를 1 증가시킨다.
- L806 : THP이고 pmd를 찾은 경우 마찬가지로 pmdp_clear_flush_young_notify()로 pmd의 AF 플래그를 클리어하고, 원래 set되어 있었으면 referenced를 1 증가시킨다.
- L810 : pmd-mapped page들은 쓰이지 않으므로 경고
- L815 : arg->mapcount를 1 차감한다
- L816 : page에 해당하는 테이블 엔트리 검색이 종료
- L818 : 함수 clear_page_idle(), test_and_clear_page_young() 둘 다 빈 함수로 아무것도 수행하지 않는다
- L823 : page에 해당하는 엔트리 중 reference가 하나라도 있었으면 arg->referenced를 1 증가시키고 arg->vm_flags에 vma->vm_flags를 or하여 추가해준다
- L828 : arg->mapcount = 0이 되면 false 리턴하여 avc interval tree 검색을 중단시킨다
- L831 : true 리턴하고 종료  

 

page_vma_mapped_walk()
- 인자로 page_vma_mapped_walk pvmw를 받는다
- page에 해당하는 pte, pmd 엔트리를 찾아서 리턴한다. 이 때 pte, pmd를 관리하는 pmd, pud struct page의 ptl lock을 잡고 내보내며, 검색이 끝날 때는 lock을 다시 풀어준다.
- pte 한 개 매핑되어 있는 경우에는 한번으로 검색이 종료된다
- pmd 한 개 매핑되어 있는 THP의 경우에도 한 번으로 검색 종료
- pte 여러 개로 쪼개져 있는 THP의 경우에만 여러 번에 걸쳐 pte 검색이 반복된다
- HugeTLBFS의 경우에는 생략
- L155 : pvmw->vma->vm_mm으로부터 mm을 가져온다
- L164 : pmd는 있고 pte는 없는 경우는 pmd로 매핑된 THP를 이전에 검색했다는 의미이므로 함수 not_found()로 검색을 종료시킨다
- L167 : HugeTLBFS인 경우이므로 생략
- L190 : page가 compound인 경우 함수 vma_address_end()로 page의 마지막 주소를 계산하고, 아니면 address + PAGE_SIZE로 마지막 주소를 계산해서 end 변수에 넣는다. 이 때 compound인 경우는 THP
- L193 : pte가 유효한 경우, 즉 이전에 pte 검색을 성공한 경우에는 next_pte로 이동한다 (pte level THP인 경우)
- L195 : restart label
- L196 : do loop 시작
- L197 : mm과 address로부터 pgd를 가져온다. 없으면 step_forward()로 한 entry 이동하고 continue
- L202 : pgd와 address로부터 p4d를 가져온다. 없으면 step_forward()로 한 entry 이동하고 continue. (arm64에서는 pgd = p4d이므로 둘 중 한번만 동작)
- L207 : p4d와 address로부터 pud를 가져온다. 없으면 step_forward()로 한 entry 이동하고 continue
- L213 : pud와 address로부터 pmd를 가져온다
- L219 : pmd 주소를 읽어서 pmd entry pmde를 가져온다
- L221 : 함수 pmd_trans_huge()로 pmde가 transparent hugepage인지 확인하고 맞으면 if 문 진입
- L222 : pmd의 ptl lock을 pvmw->ptl에 달아준다
- L223 : pmde를 다시 읽어서 pmd_trans_huge()로 체크한 뒤 참이면 pmde가 가리키는 page가 현재 검색하는 page와 동일한지 체크하고 참이면 true, 아니면 not_found()로 false 리턴
- L231 : migration 관련으로 패스
- L246 : pmd가 valid 하지 않은 경우 step_forward()로 한 entry 이동하고 continue
- L261 : 함수 map_pte()로 pte가 mapping되어 있는지 체크. 안되어 있으면 next_pte로 이동
- L263 : this_pte
- L264 : 함수 check_pte()로 pte의 pfn 범위가 page와 일치하는지 체크하고 맞으면 true 리턴
- L266 : next_pte
- L267 : do loop 시작
- L268 : pvmw->address를 페이지 만큼 증가
- L269 : end보다 address 커지면 not_found() 종료
- L272 : address가 pmd 범위를 벗어나면 ptl lock을 풀고 ptl, pte 모두 NULL로 하고 restart로 다시 시작
- L281 : pvmw->pte를 1 이동
- L282 : sync 관련으로 패스
- L286 : pte가 invalid하면 while 문 반복하여 다음 pte로 이동
- L288 : ptl이 없으면 현재 pmd ptl 달아주고 lock
- L292 : 현재 pte 가지고 this_pte로 이동
- L293 : address가 end보다 작으면 계속 while loop 수행
- L295 : 못 찾고 나오면 false 리턴  

 

not_found()
- page_vma_mapped_walk_done() 함수 호출 후 false 리턴

 

page_vma_mapped_walk_done()
- CONFIG_HIGHPTE = n이므로 함수 pte_unmap()은 NOP이다
- 그러므로 pvmw->ptl에 lock이 달려있으면 그 lock을 풀어주는 역할만 한다

 

pgd_offset()
- mm->pgd와 address로부터 pgd entry 주소 리턴

 

p4d_offset()
- 그냥 pgd 리턴

 

pud_offset()
- p4d와 address로부터 pud entry 주소 리턴

 

pmd_offset()
- pud와 address로부터 pmd entry 주소 리턴

 

pgd_present()
- 무조건 1 리턴

 

p4d_present()
- 그냥 pgd 값 리턴

 

pud_present()
- pte_present() 매크로 호출

 

pte_present()
- PTE_VALID (0번째 bit = 1) 이거나
- PTE_PROT_NONE (58번 째 bit = 1) 인지 체크한다
- 0번 째 bit는 MMU HW에서 사용하고 아키텍처에서 정의되어 있으나 58번째 bit는 HW/아키텍처와 무관하게 SW에서 특정 용도로 사용 중이다

pmd_trans_huge()
- pmd 값이 존재하고 pmd의 0번째 bit가 1이고 (valid), 1번째 bit가 0이면 (not table entry) true

 

map_pte()
- 인자로 pvmw를 받아서 pte가 mapping되어 있는지 체크한다
- L18 : pvmw->pmd와 pvmw->address로부터 pte를 구해서 pvmw->pte에 달아준다
- L19 : pvmw->flags = 0이므로 진입
- L20 : migration 아니므로 패스
- L39 : swap pte인 경우 device page이면 정상적으로 true 리턴하고 아니면 false 리턴하는 것으로 보인다
- L47 : pte_present()로 pvmw->pte 유효성 체크하고 무효이면 false 리턴
- L51 : pmd가 들어있는 pude page의 ptl lock을 pvmw->ptl에 달아준다
- L52 : pvmw->ptl lock을 잡는다
- L53 : true 리턴

 

check_pte()
- 인자로 pvmw를 받는다
- L91 : migration pass
- L102 : swap pass
- L113 : pvmw->pte present가 아니면 false 리턴
- L116 : 함수 pte_pfn()으로 pte가 가리키는 page pfn을 구한다
- L119 : 함수 pfn_is_match()로 page와 pfn이 매칭되는지 체크하고 리턴

 

pfn_is_match()
- L62 : compound page가 아니면 pfn이 정확히 매칭되는지 체크
- L65 : THP인 경우 THP 범위내에 pfn이 들어오는지 체크

 

rmap_walk()
- L2370 : page가 파일인 경우 rmap_walk_file()을 unlocked으로 수행

 

rmap_walk_file()
- anon과 유사하나 다음 측면에서 다름
1. mapping에 anon vma 대신 address space 구조체가 달림
2. mapping->i_mmap이 interval tree root가 된다
3. vma가 interval tree node로 직접 달려있다 (avc 같은게 없음)

 

- L2323 : page->mapping에서 address_space mapping을 가져온다
- L2333 : page가 locked가 아니면 버그
- L2335 : mapping 없으면 그냥 리턴
- L2338 : page의 pgoff 시작과 끝을 구한다
- L2340 : 인자 locked = false이면 i_mmap_lock_read()로 mapping->i_mmap_rwsem의 down read lock을 잡는다
- L2342 : 매크로 vma_interval_tree_foreach()로 mapping->i_mmap에 달려있는 vma 중 page pgoff 영역과 겹치는 것을 차례로 방문한다
- L2344 : 구한 vma를 이용하여 page의 vma_address()를 구한다
- L2347 : might_sleep()
- L2348 : rwc->invalid_vma가 있으면 호출하여 vma가 유효한지 체크, 무효이면 continue로 다음 vma로 이동
- L2352 : rmap_one() 호출, anon과 동일하게 page_referenced_one()을 호출
- L2354 : rwc->done이 있으면 역시 호출하여 중단 조건을 체크하고 체크되면 loop를 종료한다
- L2358 : done
- L2359 : locked = false이면 i_mmap_unlock_read()으로 mapping->i_mmap_rwsem의 up read lock을 수행한다


shrink_inactive_list() <— 다음 차례


follow_trans_huge_pmd(), page_mlock_one() 등 여러 함수에서 vma->vm_flags가 VM_LOCKED인지 체크해서 함수 mlock_vma_page()으로 TestSetPageMlocked() 수행으로 page를 Mlock 시키게 된다

 

page가 Mlock되기 전에 reclaim되면 try_to_unmap()에서 unmap을 중단하고 swap 등도 취소하게 된다

 

관련 패치
https://github.com/torvalds/linux/commit/5a9bbdcd29adbb786c53eba1dfc3c2d256020d6b
https://github.com/torvalds/linux/commit/b291f000393f5a0b679012b39d79fbc85c018233
- 원래는 VM_LOCKED이면 referenced를 증가시켜 active list에 유지시킴으로써 reclaim을 방지함
- 이후 unevictable list와 MLOCKED 페이지 플래그가 생기면서 referenced 증가를 제거하고 대신 MLOCKED 및 unevictable로 분류해주는 방식으로 바뀜

번호 제목 글쓴이 날짜 조회 수
공지 [공지] 스터디 정리 노트 공간입니다. woos 2016.05.14 617
162 [커널 18차] 76-77주차 kkr 2022.11.12 371
161 [커널 19차] 24주차 Min 2022.10.31 107
160 [커널 17차] 112주차 ㅇㅇㅇ 2022.10.30 81
159 [커널 18차] 75주차 kkr 2022.10.29 40
158 [커널 17차] 107 ~ 111주차 ㅇㅇㅇ 2022.10.23 70
157 [커널 19차] 22주차 Min 2022.10.17 76
156 [커널 18차] 73주차 kkr 2022.10.15 38
155 [커널 18차] 72주차 kkr 2022.10.09 175
154 [커널 18차] 71주차 kkr 2022.10.01 69
153 [커널 18차] 70주차 kkr 2022.09.24 74
152 [커널 18차] 69주차 kkr 2022.09.22 53
151 [커널 17차] 105~106주차 ㅇㅇㅇ 2022.09.18 50
» [커널 17차] 104주차 ㅇㅇㅇ 2022.09.04 87
149 [커널 18차] 67주차 kkr 2022.09.03 135
148 [커널 17차] 103주차 ㅇㅇㅇ 2022.08.28 35
147 [커널 18차] 66주차 kkr 2022.08.27 70
146 [커널 17차] 101~102주차 ㅇㅇㅇ 2022.08.21 44
145 [커널 18차] 65주차 kkr 2022.08.20 26
144 [커널 18차] 64주차 kkr 2022.08.13 71
143 [커널 17차] 100주차 [1] ㅇㅇㅇ 2022.08.06 98
XE Login