Page fault (Pintos, 발표자료)

Devkty·2025년 6월 12일
post-thumbnail

Page fault

해당 페이지 폴트는 Pintos x86_64 기준으로 설명합니다.

Page fault란?

Page fault는 프로세스가 참조하려는 가상 메모리 페이지가 현재 물리적 메모리에 로드되어 있지 않을때 발생합니다. 이것은 메모리 접근 시도 중에 발생하는 인터럽트나 예외 상황입니다.
즉, CPU가 아직 메모리에 존재하지 않는 가상 주소를 접근하려고 할 때 발생하는 예외(Exception)입니다.

기본 작동 방식

  1. 페이지 폴트 발생: 프로세스가 메모리에 접근하려 할 때, 해당 가상 주소에 대응하는 페이지가 물리적 메모리에 없으면 발생합니다.
  2. 인터럽트 처리: 페이지 폴트는 OS에 의해 처리되는 인터럽트입니다. OS는 이 인터럽트를 받고 현재 CPU의 상태를 저장한 후 페이지 폴트 처리 루틴을 실행합니다.
  3. 페이지 로딩: OS는 필요한 페이지를 찾아 물리적 메모리로 로드합니다. 이 페이지는 디스크의 스왑 영역이나 해당 파일 시스템에서 가져올 수 있습니다.
  4. 페이지 테이블 업데이트: 페이지가 메모리에 로드된 후, 페이지 테이블이 업데이트되어 새로운 매핑 정보를 반영합니다.
  5. 프로세스 재개: 페이지 로딩이 완료되면, CPU는 원래의 프로세스를 재개합니다.

Pintos에서 코드로 알아보기

1. 페이지 폴트 발생 (page_fault)

VM 구현 전에는 즉시 프로세스를 종료했으나 VM 구현한 후에는 vm_try_handle_fault() 을 호출합니다.

→ 접근 주소가 user, kernel, write 중 어떤 상황인지 판단하여 넘깁니다.

2.핸들러 폴트 처리 (vm_try_handle_fault)

spt_find_page 를 통해 유효한 사용자 주소인지 확인하고, spt에서 faulting address에 대한 struct page 를 찾습니다.

찾았으면, lazy load 또는 swap-in 을 하고,
없으면, 프로그램의 인자나 주소등을 저장하기 위한 스택 증가를 위해 vm_stack_growth 를 실행합니다.
커널 영역 접근, 읽기 전용 페이지 쓰기, 할당되지 않은 주소 등 유효하지 않으면 프로세스를 kill 종료

3.프레임 할당 (vm_do_claim_page)

palloc을 통해 페이지 프레임을 할당하고 mmu를 설정합니다.
만약, 백업 데이터가 있으면 swap_in 을 통해 load를 호출합니다.

pml4_set_page를 통해 물리 프레임과 가상 주소를 매핑해줍니다.

4. 구체적인 페이지로 전환 (swap_in)

마지막 코드인 return swap_in 을 통해 uninit_initialize 함수 실행을 합니다. 해당 함수는 lazy loading 방식으로 초기화된 uninitialized page를 실제 anon, file, cache 등의 구체적인 페이지로 전환(변환) 하는 함수입니다.

이후에는 lazy_load_segment를 진행하게 됩니다.

5. lazy 로딩 구현 (lazy_load_segment)

lazy_load_segment 함수를 통해 프로세스가 실제로 페이지에 접근할 때까지 해당 페이지의 데이터를 로딩하지 않고 기다리는 방식 (lazy loading)을 구현합니다. 내부에 있는 load_segment 함수에서 vm_alloc_page_with_initializer 함수를 통해 프레임에 데이터를 채우기도 합니다.

전체적인 흐름도

피그마를 통해 그려본 Pintos의 Page Fault 흐름도 입니다. 대략적인 흐름 파악을 해보시면 좋을 것 같습니다.

+ 프레임에 데이터 채움 (vm_alloc_page_with_initializer)

그러면, 프레임에는 어떻게 데이터를 채울까?
vm_alloc_page_with_initializer 라는 함수를 통해 채웁니다.

데이터를 채우는 방식에는 4가지 방식이 있습니다.

  1. 파일 시스템에서 읽기
  2. swap에서 복원하기
  3. 전부 0으로 초기화하기
  4. 공유된 페이지 그대로 사용하기

→ 위의 적절한 방식에따라 프레임에 데이터를 처리하게 됩니다.

+ PML4에 해당 매핑을 반영

pml4_set_page() 함수를 사용해 가상주소를 물리 주소로 매핑

느낌점

  • 앞서 보여두린 테스트케이스 통과 사항을 보면 아시겠지만, 중간중간 진도를 나가기 위해 해결되지 않은 테스트 케이스가 많습니다. 아직까지도 해결하지 못한것에 아쉬워서 나중에 수료 이후에도 해봐야겠습니다.
  • 평소에는 권호님이나 재준이님이나 기윤님께 도움을 받아 디버깅을 받을땐 몰랐는데, 이번에 팀활동을 하면서 팀원의 코드를 디버깅해보니 남의 코드를 이해하고 문제점을 찾는 것이 쉬운 일이 아님을 알게되었습니다. 이러한 과정을 겪으면서 코드에 대한 이해도는 확실히 늘어나는것 같습니다. 도와주신분들께 감사함을 느낍니다.
  • vm 구현부터 어려운 개념과 코드가 상당히 많았는데, 아직까지 로직이 어떻게 돌아가는지 모르는 부분도 많다고 느낍니다. 마치 이 두개의 사진이 저의 상황을 적절히 표현한게 아닐까요? 오늘 하루동안 정리를 해보며 Pintos를 마무리해봐야겠습니다.
profile
모든걸 기록하며 성장하고 싶은 개발자입니다. 현재 크래프톤 정글 8기를 수료하고 구직활동 중입니다.

0개의 댓글