[PintOS] Project 3 : VM - vm.c 코드 복기

CorinBeom·2025년 6월 9일

PintOS

목록 보기
17/19
post-thumbnail

✍️ [PintOS] vm.c 흐름 및 동작 이해 퀴즈 정리

🎯 서론

PintOS 가상 메모리 구현 파일 vm.c 전체를 기반으로, 내부 함수의 동작 방식과 흐름을 퀴즈 형식으로 복습했다.
단순히 함수별 역할을 외우기보다는 "왜 이렇게 작동하는가?", "어떤 조건에서 호출되는가?" 같은 맥락 중심의 문제들로 구성했다. 문제는 GPT가 내줬다.


✅ Q1. vm_try_handle_fault() 동작 흐름 요약

문제 요약
페이지 폴트 발생 시 호출되는 vm_try_handle_fault()의 흐름을 설명하라.

  • 스택 확장은 언제 발생하는가?
  • spt_find_page()가 NULL일 경우 어떻게 되는가?
  • writable 검증은 어떻게 처리되는가?

풀이 요약

  • not_present == true이면 해당 주소에 매핑된 물리 페이지가 없다는 의미
  • 이때 주소가 RSP 근처거나 스택 영역 안이면 vm_stack_growth() 호출
  • 그 외의 경우 spt_find_page()로 보조 페이지 테이블을 확인
    • 없다면 → exit(-1)
    • 쓰기 요청인데 !page->writableexit(-1)
  • 이상 없다면 vm_do_claim_page(page) 호출로 페이지 확보

포인트

  • 스택 자동 확장 조건: user_rsp - 8 == addr 또는 USER_STACK - (1 << 20) <= user_rsp < addr < USER_STACK
  • write 보호 위반 시도는 즉시 종료

✅ Q2. vm_get_frame()이 evicted frame을 반환하는 조건

문제 요약
다음 중 교체된 frame을 반환할 수 있는 조건은?

  • A. palloc_get_page()가 NULL일 경우

풀이 요약

  • palloc_get_page()가 실패하면 → 메모리 부족
  • calloc()으로 할당한 frame 구조체는 free()로 해제
  • 그 후 vm_evict_frame() 호출 → 교체 프레임 확보
  • 기존 페이지 연결 해제 후 frame을 재사용

포인트

  • evict 상황은 메모리 부족(palloc 실패)에서만 발생
  • cnt_page == 0, frame already connected 같은 조건은 무관

✅ Q3. vm_alloc_page_with_initializer()의 누락된 처리

문제 요약
새로운 페이지 생성 후 어떤 처리를 해줘야 하는가?

풀이 요약

  • calloc()으로 새 struct page 할당
  • uninit_new()로 lazy loading 준비
  • → 반드시 spt_insert_page(spt, newpage)로 SPT에 등록 필요
    → 안 하면 이후 page faultspt_find_page()로 찾을 수 없음

포인트

  • 실제 할당은 lazy-load지만 구조체는 미리 등록해야 한다

✅ Q4. file-backed 페이지 복사 시 틀린 설명은?

문제 요약

  • D. newpage->operationsanon_initializer로 설정된다

풀이 요약

  • 정답 D는 틀림: newpage->operations = page->operations로 복사
  • 실제로는 file-backed이면 file_ops가 설정됨

포인트

  • file-backed 페이지 복사 시:
    • 파일은 file_duplicate()로 복사
    • 프레임은 공유 (cnt_page++)
    • pml4_set_page()로 다시 매핑

✅ Q5. vm_get_victim()이 모든 accessed 비트가 true일 때

문제 요약
Clock 알고리즘에서 모든 프레임이 accessed==true면?

풀이 요약

  • 현재 구현은 clock pointer가 없음
  • 모든 페이지가 accessed면 1바퀴 돌면서 accessed 비트만 0으로 초기화
  • 결국 2바퀴 째에 맨 앞에 있는 frame을 선택하게 됨 (비효율적)

포인트

  • 실제 Clock 알고리즘은 pointer를 이동시키며 가장 먼저 accessed==false인 frame을 찾음
  • 이 구현은 그 구조가 빠져 있어 O(n) 한 바퀴 후 “맨 앞”으로 fallback함

✅ Q6. install_page() 호출이 필요한 경우

문제 요약
다음 중 install_page() 호출이 필요한 타입은?

  • C. VM_UNINIT

풀이 요약

  • UNINIT 페이지는 vm_do_claim_page()에서 바로 install_page() 호출
    → 왜냐면 lazy initializer는 호출 전에 이미 MMU 매핑이 필요함
  • ANON / FILE은 swap_in()에서 처리되므로 필요 없음

포인트

  • UNINIT만 MMU 매핑이 미리 필요
  • ANON/FILE은 swap 시스템에서 처리되므로 바로 install 안 해도 됨

✅ 마무리 요약

이 퀴즈를 통해 다음과 같은 포인트들을 확실히 정리할 수 있었다:

  • vm_try_handle_fault()는 stack growth와 lazy loading을 구분해서 처리함
  • frame이 부족하면 evict 과정이 자동으로 개입됨
  • install_page()는 UNINIT 전용
  • file-backed 페이지는 frame을 공유하지만 구조체는 복사됨
  • Clock 알고리즘은 구현에 따라 성능 차이가 크다

단순히 코드를 읽는 것보다 이런 식으로 조건 분기와 흐름을 직접 따라가며 퀴즈를 푸는 방식이 확실히 깊은 이해에 도움이 되었다.

profile
Before Sunrise

0개의 댓글