[커널 17차] 120 ~ 121주차

2023.01.08 16:24

ㅇㅇㅇ 조회 수:111

Memory ballooning
- https://velog.io/@pmw1130/ballooning
- VM 시스템에서 host 메모리 부족시 guest OS로부터 메모리 회수하고, 다시 메모리가 확보되면 할당할 수 있도록 일종의 fake process를 만들어서 inflate, deflate를 통해 메모리를 회수/할당한다


Compaction 이론
- http://jake.dothome.co.kr/zonned-allocator-compaction/
- http://jake.dothome.co.kr/zonned-allocator-isolation/
- http://jake.dothome.co.kr/zonned-allocator-migration/
- https://lwn.net/Articles/368869/
- https://lwn.net/Articles/817905/


__alloc_pages_slowpath()
- L4898 : compaction priority를 default priority로 설정
- L4939 : direct reclaim을 할 수 있고, costly order (=3) 이거나 order > 0 이고 migrate type이 movable이 아니면서 gfp mask가 watermark check를 우회할 수 있는 pfmemalloc이 아니면
- L4943 : 일단 __alloc_pages_direct_compact() 함수로 INIT_COMPACT_PRIORITY (최하위, async compaction) 순위로 일단 compaction 시도한다
- L4947 : compaction으로 page 확보되면 got_pg로 이동
- L4954 : page 확보 안되었고 costly order이면서 __GFP_NORETRY이면
- L4972 : compaction 결과가 COMPACT_SKIPPED 또는 COMPACT_DEFERRED인 경우 nopage로 이동
- L4981 : 아니면 compaction priority를 INIT_COMPACT_PRIORITY로 하고 아래에서 reclaim과 compaction을 시도한다


__alloc_pages_direct_compact()
- L4353 : order == 0이면 NULL 리턴
- L4357 : current->flags의 PF_MEMALLOC 여부를 noreclaim_flag에 기록하고 current->flags에 PF_MEMALLOC 추가
- L4359 : try_to_compact_pages()으로 compaction 수행
- L4362 : current->flags의 PF_MEMALLOC 값 복원
- L4365 : compaction 결과가 COMPACT_SKIPPED이면 NULL 리턴
- L4374 : compaction으로 page 확보되면 prep_new_page() 함수로 page 사용 준비
- L4378 : page 확보 안되었으면 get_page_from_freelist()로 다시 시도
- L4381 : page 확보되면 page의 zone에 대해 다음 작업 수행
- L4384 : zone->compact_blockskip_flush = false
- L4385 : compaction_defer_reset() 함수로 defer tracking counter reset
- L4387: page 리턴
- L4396 : cond_resched()
- L4398 : NULL 리턴


compaction_defer_reset()
- 인자로 zone, order, alloc_success를 받는다
- L200 : alloc_success = true이면 zone->compact_considered, zone->compact_defer_shift 모두 0으로 리셋
- L204 : order >= zone->compact_order_failed 이면 zone->compact_order_failed = order + 1


try_to_compact_pages()
- L2554 : may_perform_io에 gfp mask에 __GFP_IO 여부를 기록
- L2557 : compact_result는 COMPACT_SKIPPED로 초기화
- L2563 : may_perform_io == false, 즉 IO를 못 쓰면 COMPACT_SKIPPED 리턴
- L2569 : zone에 대해 루프 수행
- L2573 : priority가 MIN_COMPACT_PRIORITY 보다 우선 순위가 떨어지고 compaction_deferred()로 skip해야하는 경우 rc가 COMPACT_DEFERRED보다 작으면 COMPACT_DEFERRED로 만들고 continue로 다음 zone을 처리
- L2579 : compact_zone_order()로 compaction 수행하고 결과를 rc에 저장
- L2584 : 성공한 경우 compaction_defer_reset()을 false로 호출하고 break. false인 이유는 아직 확실하게 성공이 아니기 때문
- L2596 : priority가 COMPACT_PRIO_ASYNC가 아니고 결과가 COMPACT_COMPLETE 이거나 COMPACT_PARTIAL_SKIPPED 이면 defer_compaction() 수행하여 defer
- L2610 : priority가 COMPACT_PRIO_ASYNC이고 need_resched() 이거나 fatal signal pending이면 break
- L2615 : rc 리턴


compaction_deferred()
- zone, order를 인자로 받아 compaction skip해야 하는지 판정
- L176 : defer_limit = 1 << zone->compact_defer_shift로 설정
- L178 : order가 zone->compact_order_failed 보다 작으면 false 리턴
- L182 : zone->compact_considered를 1 증가시키고 defer_limit 보다 크거나 같으면 defer_limit으로 cap한 뒤 false 리턴
- L189 : 아니면 true 리턴


defer_compaction()
- 인자로 zone, order를 받는다
- L161 : zone->compact_considered = 0 으로 리셋
- L162 : zone->compact_defer_shift++
- L164 : order < zone->compact_order_failed 이면 zone->compact_order_failed = order로 줄여줌
- L167 : zone->compact_defer_shift > COMPACT_MAX_DEFER_SHIFT = 6이면 COMPACT_MAX_DEFER_SHIFT으로 조정


compact_zone_order()
- L2486 : compact_control cc를 설정
- L2500 : capture_control capc를 설정
- L2510 : barrier()로 cc, capc가 제대로 설정되도록 함
- L2511 : current->capture_control에 capc를 write
- L2513 : compact_zone()으로 compaction 수행
- L2523 : current->capture_control을 NULL로 만든다
- L2524 : capc.page가 있으면 COMPACT_SUCCESS 리턴


compact_zone()
- compact control cc, capture control capc를 받는다
- L2272 : cc->zone으로부터 zone의 start pfn, end pfn을 계산한다
- L2275 : cc->mode가 SYNC인지 ASYNC인지를 sync에 기록한다. MIGRATE_ASYNC가 아니면 sync
- L2282 : cc의 total_migrate_scanned, total_free_scanned, nr_migratepages, nr_freepages 0으로 초기화
- L2286 : cc->free_pages, cc->migratepages list_head 초기화
- L2289 : cc->gfp_mask로부터 cc->migratetype을 받는다. unmovable, movable, reclaimable 중 하나
- L2290 : compaction_suitable() 함수로 compaction 적합 여부를 계산하여 ret에 저장. 결과는 COMPACT_SUCCESS : compaction 안해도 이미 요청한 order에 해당하는 빈 페이지 존재, COMPACT_SKIPPED : 메모리 파편화가 문제가 아니라 부족이 문제라 compaction 안함, COMPACT_CONTINUE : 메모리 파편화 심해서 compaction 해야 함 3가지 중 하나임
- L2293 : 판단 결과 compaction 할 필요 없는 경우, COMPACT_SUCCESS 또는 COMPACT_SKIPPED 이면 ret 리턴
- L2303 : compaction_restarting() 함수로 compaction restart를 해야 하는지 보고 해야하면 __reset_isolation_suitable() 수행하여 zone의 pageblock들의 skip bit를 clear한다
- L2312 : cc->fast_start_pfn = 0
- L2313 : cc->whole_zone이 참이면 cc->migrate_pfn은 start_pfn, cc->free_pfn는 pageblock end pfn으로 설정한다
- L2316 : 아니면 cc->migrate_pfn은 cc->zone->compact_cached_migrate_pfn, cc->zone->free_pfn은 cc->zone-> compact_cached_free_pfn으로 설정하고 zone boundary에 맞게 조정한다. (zone 범위 벗어나면 migrate pfn은 start pfn으로, free pfn은 end pfn으로 조정하고 cache도 각각 재설정
- L2329 : cc->migrate_fpn <= cc->zone->compact_init_migrate_pfn이면 cc->whole_zone = true로 설정
- L2333 : last_migrated_pfn = 0으로 설정
- L2343 : async이고 cache된 migrate pfn이 sync, async가 동일하면 update_cached = true로 설정, 아니면 false
- L2350 : lru_add_drain()으로 pagevec percpu flush
- L2352 : compact_finished() == COMPACT_CONTINUE 인 동안 while 문 수행 <— 분석 중


compaction_restarting()
- 인자로 zone, order를 받는다
- L213 : order < zone->compact_order_failed 이면 false 리턴 (restart 안함)
- L216 : zone->compact_defer_shift가 이미 최대값인 COMPACT_MAX_DEFER_SHIFT으로 올라 왔고, 또 zone->compact_considered (counter)가 역시 최대값인 1 << zone->compact_defer_shift 보다 같거나 크면 true 리턴


__reset_isolation_suitable()
- zone을 받는다
- L333 : migrate_fpn은 zone start pfn에서 시작
- L334 : free_fpn은 zone end pfn에서 시작
- L335 : reset_migrate는 zone end pfn에서 시작
- L336 : reset_free는 zone start pfn에서 시작
- L337 : source_set, target_set = false
- L340 : zone->compact_blockskip_flush == false이면 skip bit reset을 안하므로 그냥 리턴
- L343 : zone->compact_blockskip_flush = true로 설정
- L351 : migrate_pfn은 위로, free_pfn은 아래로 pageblock page 만큼 이동하면서 만날때까지 루프 수행
- L353 : cond_resched()
- L356 : __reset_isolation_pfn()으로 migrate_pfn의 pageblock의 skip bit를 clear하고 (reset), reset된 migrate pfn을 zone->compact_init_migrate_pfn, zone->compact_cached_migrate_pfn[0], zone->compact_cached_migrate_pfn[1]에 기록한다. 기록은 skip bit clear한 첫 pfn에 대해서만 수행한다
- L366 : __reset_isolation_pfn()으로 free_pfn의 pageblock의 skip bit를 clear하고 (reset), reset된 free pfn을 zone->compact_init_free_pfn, zone->compact_cached_free_pfn에 기록한다. 기록은 skip bit clear한 첫 pfn에 대해서만 수행한다
- migrate fpn의 경우 처음에는 LRU page에 대해서, free pfn의 경우 처음에는 buddy page에 대해서만 skip bit clear를 시도하고, 다음부터는 둘 다 LRU 또는 buddy page 모두에 대해 수행한다
- L373 : 루프 종료
- L376 : migrate 또는 free pfn에 대해 skip bit clear가 안되었을 경우 cache pfn에 zone pfn의 중간 값을 기록한다


__reset_isolation_pfn()
- zone, pfn, check_source, check_target을 받는다
- L260 : pfn에 해당하는 page를 구한다
- L265 : page 없거나 page와 zone이 안맞거나 page compound order가 pageblock order보다 크면 false 리턴
- L276 : check source, check target이 true이고 pageblock skip bit이 이미 0이면 true 리턴. 이 부분은 이미 이전에 pageblock skip bit clear를 한 적이 있어야 들어올 수 있으며 true 리턴은 의미가 없음
- L283 : check source false, check target true이고 pageblock migratetype이 movable이 아니면 false 리턴. 즉 free pfn에 대해 첫 clear 시도 중인 경우에는 movable만 clear 허용된다
- L288 : pfn으로부터 pageblock start pfn을 구하고 zone start pfn에 맞춰준다. 마찬가지로 마지막 pfn도 pageblock end pfn을 zone end pfn에 맞춰준다
- L308 : 시작 pfn이 끝 pfn보다 커질 때까지 또는 clear bit 성공할 때까지 루프를 돌면서 check source & LRU page 또는 check target & Buddy page인 경우 pageblock skip bit을 clear하고 true 리턴한다. page에 대해 clear 안되면 costly order, 즉 3에 해당하는 8 페이지 만큼 이동하고 다시 수행한다
- L323 : 모든 페이지에 대해 돌았는데 clear 안되면 false 리턴


compact_finished()
- 인자로 compact control cc를 받는다
- L2140 : __compact_finished()를 수행하고 결과를 리턴. 만약 결과가 COMPACT_NO_SUITABLE_PAGE이면 COMPACT_CONTINUE 리턴


__compact_finished()
- 인자로 compact control cc를 받는다
- L2029 : migratetype에 cc->migratetype을 받는다
- L2033 : cc->free_pfn과 cc->migrate_fpn이 만나면 if 문 수행
- L2035 : zone의 cache된 migrate pfn, free pfn을 각각 zone start, end pfn으로 reset
- L2043 : cc->direct_compaction인 경우 cc->zone->compact_blockskip_flush = true 설정
- L2046 : cc->whole_zone이면 COMPACT_COMPLETE, 아니면 COMPACT_PARTIAL_SKIPPED 리턴
- L2050 : if 문 종료
- L2052 : proactive compaction인 경우, 즉 background로 자동 수행되는 compaction인 경우 if 문 진입
- L2056 : kswapd가 수행 중이면 reclaim 방해할 수 있으므로 COMPACT_PARTIAL_SKIPPED 리턴 종료
- L2060 : fragmentation_score_zone()로 score 계산
- L2061 : fragmentation_score_wmark()로 기준치 계산
- L2063 : score가 기준치보다 크면 ret = COMPACT_CONTINUE, 아니면 COMPACT_SUCCESS으로 설정하고 out으로 이동
- L2069 : if 문 종료
- L2071 : shell 명령 compact_memory에 따른 compaction이면 COMPACT_CONTINUE 리턴
- L2080 : cc->migrate_pfn이 pageblock align 안되어 있으면 COMPACT_CONTINUE 리턴
- L2084 : ret = COMPACT_NO_SUITABLE_PAGE 설정
- L2085 : order를 cc->order에서 max order까지 루프 수행
- L2086 : area = zone->free_area[order]를 가져온다
- L2090 : area에 page가 있으면 COMPACT_SUCCESS 리턴
- L2095 : migrate type == movable이고 MIGRATE_CMA area에 page가 있으면 COMPACT_SUCCESS 리턴
- L2103 : find_suitable_fallback()으로 fallback할 수 있으면 if 문 진입
- L2107 : migrate type == movable이면 COMPACT_SUCCESS 리턴
- L2118 : async이거나 cc->migrate_pfn이 pageblock align이 맞으면 COMPACT_SUCCESS 리턴
- L2124 : ret = COMPACT_CONTINUE 설정하고 break
- L2127 : if 문 및 루프 종료
- L2129 : out
- L2130 : cc->contended 이거나 fatal signal pending이면 ret = COMPACT_CONTENDED
- L2133 : ret 리턴


fragmentation_score_zone()
- extfrag_for_order() 호출


extfrag_for_order()
- L1126 : fill_contig_page_info()로 info 계산
- L1130 : free page 중 free blocks suitable page가 아닌 비율 계산하여 리턴


fragmentation_score_wmark()
- L2011 : 100 - sysctl_compaction_proactiveness로 wmark_low 계산, 최소 5로 설정
- L2012 : low가 참이면 wmark_low, 아니면 wmark_low + 10, 최소 100 리턴

번호 제목 글쓴이 날짜 조회 수
공지 [공지] 스터디 정리 노트 공간입니다. woos 2016.05.14 626
186 [커널 19차] 41 주차 이태백 2023.03.04 101
185 [커널 18차] 93주차 kkr 2023.03.04 54
184 [커널 18차] 91주차 kkr 2023.02.18 97
183 [커널 19차] 39 주차 Min 2023.02.18 53
182 [커널 18차] 90주차 kkr 2023.02.13 63
181 [커널 19차] 38 주차 Min 2023.02.11 45
180 [커널 19차] 37 주차 Min 2023.02.04 478
179 [커널 19차] 36 주차 Min 2023.01.28 85
178 [커널 18차] 88주차 kkr 2023.01.28 55
177 [커널 19차] 35 주차 Min 2023.01.14 93
» [커널 17차] 120 ~ 121주차 ㅇㅇㅇ 2023.01.08 111
175 [커널 18차] 85주차 kkr 2023.01.07 53
174 [커널 19차] 34 주차 Min 2023.01.07 42
173 [커널 18차] 84주차 kkr 2022.12.31 104
172 [커널 19차] 33 주차 Min 2022.12.31 51
171 [커널 17차] 117 ~ 119주차 ㅇㅇㅇ 2022.12.25 62
170 [커널 19차] 31 주차 Min 2022.12.17 63
169 [커널 19차] 30 주차 Min 2022.12.10 61
168 [커널 17차] 112 ~ 116주차 ㅇㅇㅇ 2022.12.05 73
167 [커널 18차] 80주차 kkr 2022.12.03 156
XE Login