[커널 17차] 112주차

2022.10.30 02:30

ㅇㅇㅇ 조회 수:81

shrink_page_list()
- L1552 : page가 THP이면 우선 split이 가능한지 묻고 안되면 activate_locked로 이동
- L1561 : page가 PMD mapcount가 0이면 split 시도하고 안되면 activate_locked로 이동
- L1566 : add_to_swap()으로 page를 swap cache에 추가
- L1567 : add_to_swap() 실패 후 page가 THP가 아니면 activate_locked_split으로 이동
- L1570 : add_to_swap() 실패 후 page가 THP이면 split 시도 후 실패하면 activate_locked로 이동
- L1576 : split 후 다시 add_to_swap() 재시도. 또 안되면 activate_locked_split으로 이동
- L1580 : add_to_swap() 성공하면 may_enter_fs를 true로 변경
- L1583 : mapping을 swap entry의 address_space로 변경
- L1586 : page가 file 인데 THP이면 역시 split 시도하고 안되면 keep_locked로 이동한다
- L1598 : page가 THP여서 split된 경우, sc->nr_scanned에서 511을 차감하고 nr_pages도 1로 조정한다
- L1608 : page가 mapped되어 있으면 unmap을 시도한다
- L1608 : unmap flag를 TTU_BATCH_FLUSH로 설정
- L1609 : page가 PageSwapBacked()이면 was_swapbacked를 true로 설정
- L1611 : page가 THP이면 flag에 TTU_SPLIT_HUGE_PMD 추가
- L1614 : try_to_unmap()으로 page를 unmap 수행
- L1615 : 여전히 page가 mapping되어 있으면 stat->nr_unmap_fail에 nr_pages를 추가하고, page가 원래 swapbacked가 아니었는데 지금 swapbacked이면 stat->nr_lazyfree_fail를 nr_pages 만큼 증가시키고 activate_locked로 이동한다
- L1623 <— 진행할 차례

 

add_to_swap()
- page를 위한 swap 공간을 할당하고, page를 SwapCache에 추가한다
- L189 : PageLocked가 아니면 버그
- L190 : PageUptodate가 아니면 버그. 이는 page fault 이후 처음으로 read할 때 setting된다
- L192 : get_swap_page() 수행하여 page를 위한 swap entry를 가져온다
- L193 : entry가 0이면 0 리턴
- L207 : 함수 add_to_swap_cache()로 page를 swap cache에 추가한다. 즉 xarray의 node에 page를 추가한다. 이 때 메모리 할당을 위해서는 __GFP_HIGH와 __GFP_NOMEMALLOC을 준다. 이는 min watermark를 절반 감소시키는 효과가 있으나 워터마크 체크를 우회할 수는 없다
- L209 : 실패하면 fail로 이동
- L225 : SetPageDirty() 수행. Dirty page가 되어야 pageout이 된다
- L227 : 1 리턴
- L229 : fail
- L230 : 함수 put_swap_page()로 swap entry를 slots_ret pcpu에 반환
- L231 : 0 리턴

 

add_to_swap_cache()
- 인자로 page, swp_entry_t entry, gfp, shadowp를 받는다
- L103 : entry로부터 swap address_space를 구한다
- L104 : entry로부터 swap offset idx를 구한다
- L105 : address_space->i_pages에서 idx에 해당하는 xarray를 page의 compound order만큼 세팅한다
- L106 : nr에 page의 thp page nr을 기록
- L109 : PageLocked()가 아니면 버그
- L109 : PageSwapCache()면 버그
- L109 : PageSwapBacked()가 아니면 버그
- L113 : page의 refcount를 nr 만큼 증가
- L114 : SetPageSwapCache()
- L116 : do while loop 시작
- L117 : xarray lock
- L118 : xarray 메모리 할당
- L119 : error 나면 unlock으로 이동
- L121 : nr만큼 for loop 수행
- L123 : xarray의 node값을 읽어서 old value를 shadowp에 전달한다
- L128 : page->private에 swap entry 값을 저장
- L129 : xarray의 node에 page를 저장한다. page가 이제 swap cache가 된다
- L130 : xarray의 다음 node로 이동한다
- L131 : for loop 종료
- L132 : address_space->nrpages를 nr 만큼 증가
- L133 : page node의 NR_FILE_PAGES 스탯을 nr 만큼 증가
- L134 : page의 lruvec NR_SWAPCACHE 스탯을 nr 만큼 증가
- L135 : swap_info.add_total stat을 nr 만큼 증가
- L136 : unlock
- L137 : xarray unlock
- L138 : while 문 종료. xarray에서 메모리 할당 실패 버그가 있었으면 다시 할당 시도하고 루프 재수행
- L140 : xarray 수행 중 에러가 없었으면 0 리턴
- L143 : 에러가 있으면 롤백. ClearPageSwapCache(), page ref nr 감소 후 xarray error를 리턴

 

 try_to_unmap()
- 인자로 page, ttu_flags flags를 받는다
- rmap walk를 수행하여 page에 해당하는 모든 pte를 unmapping하고, 만약 anon page인 경우네는 pte에 swap entry를 기록한다
- L1674 : rmap walk control을 만든다. rmap_one 함수는 try_to_unmap_one()으로 이게 하나의 vma에 해당하고, 종료 조건인 done 함수는 page_not_mapped()이다. anon_lock 함수는 page_lock_anon_vma_read()으로 이전 page referenced check했을 때와 동일하다
- L1684 : rmap_walk() 함수를 수행한다

 

try_to_unmap_one()
- 인자로 page, vma, address, arg를 받는다
- L1397 : pte 검색을 위한 page via mapped walk, pvmw 구조체를 만든다
- L1406 : arg에서 flags를 만든다
- L1414 : TTU_SYNC 아니므로 생략
- L1417 : TTU_SPLIT_HUGE_PMD이므로 함수 split_huge_pmd_address()로 THP page를 분리한다
- L1428 : mmu notifier 관련은 생략
- L1437 : CONFIG_ARCH_WANT_HUGE_PMD_SHARE = n이므로 빈 함수이다
- L1442 : 함수 page_vma_mapped_walk()로 page 및 vma에 해당하는 pte를 가져온다
- L1446 : flags가 TTU_IGNORE_MLOCK이 아니면서 vma->vm_flags는 VM_LOCKED이면
- L1454 : page가 TransCompound가 아니거나, page가 head이고 doublemap이 아니고 동시에 anon이 아니면 함수 mlock_vma_page()로 page를 mlock으로 만든다. 즉 THP이면서 doublemap이거나 anon이면 mlock으로 만들지 않는다
- L1457 : pmd page table lock을 풀고 false를 리턴한다
- L1463 : pte가 리턴되지 않고 pmd가 리턴되면 버그
- L1468 : huge page는 일단 패스
- L1503 : flush_cache_page()는 빈 함수
- L1504 : CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH = n이므로 should_defer_flush() = false
- L1517 : ptep_clear_flush()로 pte를 clear하고 tlb로 flush한다. 이전 pte 값은 pteval에 저장한다
- L1521 : pteval이 dirty이면 page의 PG dirty를 참으로 만든다
- L1525 : update_hiwater_rss() high watermark를 늘려준다
- L1527 : PageHWPoison()은 생략
- L1539 : pte_unused()는 빈 함수
- L1554 : PageAnon()인 경우 else if 문 진입
- L1555 : page private로부터 swap entry를 가져온다
- L1561 : PageSwapBacked() 및 PageSwapCache() 모두 참 또는 거짓(lazy free)일 것이므로 패스
- L1572 : PageSwapBacked()가 아닌 경우, 즉 lazy free인 경우 PageDirty()가 아니면 mm의 MM_ANONPAGES를 1 줄이고 discard로 이동한다
- L1585 : PageDirty()인 경우에는 pte를 원래 값으로 복원하고 SetPageSwapBacked()를 수행한 뒤 false 리턴
- L1592 : swap_duplicate()로 swap map count를 1 증가시킨다
- L1598 : arch_unmap_one()은 빈 함수
- L1604 : mm->mmlist가 빈 리스트이면 init_mm.mmlist에 달아준다
- L1610 : mm의 MM_ANONPAGES를 1 줄이고 MM_SWAPENTS를 1 증가
- L1612 : swap entry를 pte 포맷으로 인코딩
- L1613 : pte_soft_dirty()는 빈 함수
- L1615 : pte_uffd_wp()도 빈 함수
- L1617 : swap entry를 pte에 기록한다
- L1632 : page가 파일이면 mm의 MM_FILEPAGES만 1 감소시킨다
- L1634 : discard
- L1642 : page_remove_rmap()으로 page의 mapcount를 1 감소시킨다
- L1643 : put_page()로 refcount 1 감소
- L1648 : 성공 여부 리턴

 

mlock_vma_page()
- page를 인자로 받는다
- L94 : PageLocked()가 아니면 버그
- L96 : PageTail()이면 버그
- L97 : PageCompound()이면서 PageDoubleMap()이면 버그
- L99 : TestSetPageMlocked()로 page를 mlocked로 변경. 실패하면 리턴
- L100 : nr_pages = page의 thp page 수
- L102 : 성공하면 page의 zone NR_MLOCK stat을 nr_pages만큼 증가
- L103 : UNEVICTABLE_PGMLOCKED event count를 nr_pages만큼 증가
- L104 : page를 isolate_lru_page()로 isolate하고 성공하면 putback_lru_page()로 pagevec이나 unevictable LRU로 page를 넣는다

 

isolate_lru_page()
- L2095 : page refcount가 0이 아니면 버그
- L2098 : TestClearPageLRU() 수행하고 실패하면 EBUSY 에러 리턴
- L2101 : 성공하면 get_page() 수행
- L2102 : lruvec에 대한 lock을 잡는다
- L2103 : lruvec에서 page 삭제
- L2104 : lruvec lock을 푼다
- L2105 : 0 리턴

 

putback_lru_page()
- L1219 : lru_cache_add()로 page를 pagevec에 추가
- L1220 : put_page() 수행

 

should_defer_flush()
- 인자로 mm_struct mm, ttu_flags flags를 받는다
- L653 : should_defer = false로 시작
- L655 : flags에 TTU_BATCH_FLUSH가 없으면 false 리턴
- L659 : mm의 cpu들 중 현재 cpu를 제외한 임의의 하나를 골라서 그것이 유효하면 should_defer = true로 설정
- L661 : put_cpu() = preempt_enable()
- L663 : should_defer 리턴

 

ptep_clear_flush()
- vma, address, ptep를 받는다
- L93 : mm = vma->vm_mm을 가져온다
- L95 : ptep를 지우고 이전 값을 pte로 가져온다
- L96 : pte_accessible()은 pte가 present 및 valid하므로 참
- L97 : flush_tlb_page()로 tlb flush 수행
- L98 : pte를 리턴

 

update_hiwater_rss()
- 인자로 mm_struct mm을 받는다
- L1990 : mm의 FILEPAGE / ANONPAGE / SHMEMPAGE 수의 합을 rss (resident set size)로 계산한다
- L1992 : mm->hiwater_rss가 rss보다 작으면 rss로 변경한다

 

swap_duplicate()
- 인자로 swap entry를 받는다
- L3507 : __swap_duplicate()로 swap map count를 1 증가
- L3509 : 0 리턴

 

__swap_duplicate()
- 인자로 swap entry, usage를 받는다
- L3433 : get_swap_device()로 entry에 대한 si를 구하고 si->users ref를 증가
- L3437 : entry에서 swap offset을 구한다
- L3438 : ci를 lock 잡고 구한다
- L3440 : p->swap_map[offset]을 count로 가져온다
- L3446 : count가 SWAP_MAP_BAD이면 에러 리턴
- L3451 : count로부터 SWAP_HAS_CACHE 플래그를 has_cache로 저장
- L3452 : count에서 플래그 제거
- L3455 : usage 1이므로 일단 패스
- L3465 : count를 1 증가
- L3478 : p->swap_map[offset]에 증가된 count를 기록
- L3481 : ci unlock
- L3483 : put_swap_device()로 si->users ref를 감소
- L3484 : err = 0 리턴

 

page_remove_rmap()
- 인자로 page, compound를 받아 mapcount를 감소시킴
- L1350 : page가 파일이면 page_remove_file_rmap()로 map count 감소
- L1355 : compound 생략
- L1361 : anon이면 page map count 1 감소시키고 -1이 안되었으면 리턴
- L1371 : mapcount가 더 이상 없으면 (-1) page mlocked 해제
- 1374 : compound 생략

 

page_remove_file_rmap()
- 인자로 page, compound를 받아 mapcount를 감소시킴
- L1257 : page huge 생략
- L1264 : compound 생략
- L1280 : page map count 1 감소 시키고 -1이면 리턴
- L1289 : page lruvec의 NR_FILE_MAPPED를 thp nr 만큼 감소
- L1291 : page mlocked 해제

번호 제목 글쓴이 날짜 조회 수
공지 [공지] 스터디 정리 노트 공간입니다. woos 2016.05.14 617
162 [커널 18차] 76-77주차 kkr 2022.11.12 371
161 [커널 19차] 24주차 Min 2022.10.31 107
» [커널 17차] 112주차 ㅇㅇㅇ 2022.10.30 81
159 [커널 18차] 75주차 kkr 2022.10.29 40
158 [커널 17차] 107 ~ 111주차 ㅇㅇㅇ 2022.10.23 69
157 [커널 19차] 22주차 Min 2022.10.17 76
156 [커널 18차] 73주차 kkr 2022.10.15 37
155 [커널 18차] 72주차 kkr 2022.10.09 175
154 [커널 18차] 71주차 kkr 2022.10.01 68
153 [커널 18차] 70주차 kkr 2022.09.24 74
152 [커널 18차] 69주차 kkr 2022.09.22 52
151 [커널 17차] 105~106주차 ㅇㅇㅇ 2022.09.18 50
150 [커널 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