Week12 WIL

gitddabong·2022년 1월 25일
0

3주차 과제 (Virtual Memory)

페이지 폴트에는 3가지 종류가 있다.

  1. lazy loading
  2. 다른 메모리와 경합, 물리 프레임과 swap out?
  3. 비정상적인 주소에 접근

1번과 2번의 경우 가상 메모리에는 찾고자하는 주소가 존재하나, 물리 메모리에는 존재하지 않는다.

이를 깃북에서는 bogus fault라고 한다.

지금까지는 위 2가지 경우도 page fault로 처리했지만,

이제는 위 경우가 발생하면 물리 메모리를 맵핑해서 페이지 폴트를 처리할 예정이다.

Memory Management

기존의 PintOS의 가상 메모리와 물리 메모리의 관계도

여기에 Supplemental page table 이라는 구조를 추가할 예정.

supplemental page table을 추가한 관계도

Supplemental Page Table

페이지 폴트 처리에 용이하게 페이지 테이블을 보완한 테이블.

비트맵, 리스트 등 여러 가지로 구현할 수 있지만 해시 테이블로 구현.

구현 1. supplemental_page_table_init()

  • 페이지 테이블을 hash 구조체로 동적 할당
  • 동적 할당한 페이지 테이블을 hash_init 으로 초기화.
    • 초기화에 필요한 page_hash , page_less 함수 만들기.
    • page_hash : page 구조체의 va를 이용해 해싱 함수를 돌려 키를 만드는 함수
    • page_less : 페이지에서 원하는 값을 리스트에서 서치할 때 사용. 함수에는 va의 대소비교를 하는 내용이 들어 있음.
  • 인자로 받은 spt에 새로 할당한 페이지 테이블을 저장.

구현 2. spt_find_page()

  • 빈 page 구조체를 선언하고 인자로 받은 va를 pg_round_down 한 값을 page 구조체의 va에 저장.
    • page 구조체는 이 함수에서 va를 이용해 해시 함수를 돌리고 그에 맞는 hash_elem을 찾기 위한 장치로만 사용됨.
    • pg_round_down(va)을 실행하면 현재 va가 가리키고 있는 위치에서 offset만큼 내림. 리턴 값은 page 구조체의 시작점을 가리키게 된다.
  • hash_findspt에서 인자로 받은 va와 같은 키를 가지는 hash_elem을 리턴한다.
    • find_bucket에서 아까 빈 page 구조체에 넣었던 va를 이용해 해시 함수를 돌려 키를 찾고 그에 맞는 bucket 위치에 있는 리스트 반환
      • 코드를 찾아 보면 해시 함수(page_hash) 를 직접 호출하는 부분이 없다. h->hash 이 부분이 실제로 함수를 호출하는 부분이다. 구현 1에서 hash_init을 실행할 때 인자로 넣어준 함수들이 함수 포인터로서 page 구조체에 저장되어 있으므로 저런 식으로 함수 호출이 가능하다.
    • find_elem으로 find_bucket이 반환해준 리스트에서 찾고자하는 va를 가진 elem 탐색
      • 여기서도 page_less 함수가 elem을 리스트에서 서치할 때 사용하는 비교 함수로써 사용됨.
  • 받아온 elem로 hash_entry를 이용해 page 구조체를 받아와서 리턴

구현 3. spt_insert_page()

  • hash_insert로 해시 테이블에 page 를 삽입하고 그 결과를 true / false로 반환

구현 4. vm_get_frame()

  • frame 구조체를 동적 할당.
  • palloc_get_page를 이용해 user pool에 페이지 할당
  • 페이지 할당 실패 시 원래는 스왑 아웃까지 처리해야하나, 지금은 PANIC(”todo”) 처리

구현 5. vm_do_claim_page()

  • 위에서 구현한 vm_get_frame()으로 frame 동적 할당 및 user pool에 페이지 할당
  • 파라미터로 받은 page 구조체와 frame 구조체를 서로 연결
  • 현재 스레드의 pml4에 page와 frame을 맵핑

구현 6. vm_claim_page()

  • 파라미터로 va를 받아서 그 va와 일치하는 페이지를 spt에서 찾아오기.
  • 그 후 위에서 구현한 vm_do_claim_page()로 페이지 폴트 처리.

흐름 정리

memory management에서 구현한 것은, 어떤 페이지 폴트인지는 잘 모르나, 페이지 폴트가 발생했을 때 그에 대한 처리로 프레임을 새로 할당하는 과정이었다.

진행 과정

  1. page fault 발생
  2. spt에서 page fault가 발생한 page 탐색 (spt_find_page())
  3. vm_get_frame()으로 user pool에 페이지 할당
  4. vm_do_claim_page()로 page, frame 연결
  5. pml4에 페이지와 프레임 관계 맵핑(pml4_set_page())

2부터 5까지의 과정은 모두 vm_claim_page() 함수를 한번 호출하면 진행되는 과정.

Anonymous Page

lazy loading이란?

메모리 로딩이 필요한 시점까지 오면 그제서야 물리 메모리에 맵핑을 하는 방식.
그 즉시 필요한 부분만 맵핑해서 메모리를 사용하므로 모든 메모리를 물리 메모리에 맵핑하는 Eager loading에 비해 오버헤드를 줄일 수 있다는 장점이 있다.

Anonymous Page란?

가상 메모리 공간에 페이지가 할당되어 있고 해당 페이지 구조가 있지만 전용 물리 프레임이 없고 실제 내용이 아직 로드되지 않은 페이지.

흐름

  1. vm_try_handle_fault 로 유효한 페이지 폴트인지 확인하고 bogus fault인 경우 일부 내용을 페이지에 로드.
  2. load_segment로 ELF 포맷 파일의 세그먼트를 디스크에서 가져와 가상 메모리에 적재.
  3. load_segment 내부의 vm_alloc_page_with_initializer 로 페이지 할당 및 초기화
  4. 위 memory management 과제에서 작성한 vm_claim_page로 물리 메모리 맵핑
profile
성장형 개발자 gitddabong

0개의 댓글