Always Be Wise

Project_3 : Virtual Memory - Memory Mapped Files(1) 본문

카이스트 정글 - 프로젝트/Pintos

Project_3 : Virtual Memory - Memory Mapped Files(1)

bewisesh91 2022. 1. 24. 15:36
728x90

anonymouse page와 달리, memory-mapped page는 file-backed mapping이다. 

페이지의 콘텐츠는 실제 파일의 데이터를 미러링 한다.

페이지 폴트 발생 시, 물리적 프레임이 즉시 할당되고 파일로부터 메모리로 콘텐츠가 복사된다.

memory-mapped page가 매핑 해제되거나 스왑 아웃되면 콘텐츠의 모든 변경 사항이 파일에 반영된다.

mmap and munmap System Call

memory-mapped 파일을 위한 두 가지 시스템 콜 mmap( )munmap( )을 구현해야 한다.

VM 시스템은 mmap 영역에서 페이지를 Lazy Loading 해야 하며, mmaped 파일 자체를 매핑을 위한 backing store로 사용해야 한다.

이 두 가지 시스템 콜을 구현하려면 vm/file.c에 정의된 do_mmap( )do_munmap( )을 구현하고 사용해야 한다.

void *mmap (void *addr, size_t length, int writable, int fd, off_t offset);

mmap 함수는 fd로 열린 열린 파일의 바이트 길이만큼 오프셋 바이트에서부터 프로세스 가상 주소 공간에 매핑한다.

전체 파일은 addr에서 시작하는 연속된 가상 페이지로 매핑된다.

파일의 길이가 PGSIZE의 배수가 아닌 경우, 일부 바이트들이 파일 뒤에 남는다.

페이지 폴트 시, 해당 바이트들을 0으로 설정하고, 페이지가 디스크에 다시 기록될 때 삭제해야 한다.

해당 함수가 성공적으로 호출될 경우 파일이 매핑된 가상 주소를 반환한다. 실패할 경우, NULL을 반환한다.

fd로 열린 파일의 길이가 0바이트인 경우, mmap 호출이 실패할 수 있다.

addr이 페이지 정렬되어 있지 않거나, 매핑된 페이지의 범위가 기존에 미리 매핑된 페이지 집합과 겹칠 경우 실패해야 한다.

Linux에서 addr이 NULL이면 커널은 매핑을 생성할 적절한 주소를 찾는다.

단순화를 위해서 Pintos에서는 가상 페이지 0은 매핑되지 않았다고 가정하며, 만약 addr이 0이라면 실패해야 한다.

길이가 0이면 mmap은 실패해야 한다. 콘솔 입출력을 나타내는 파일 디스크립터는 매핑이 불가능하다.

memory-mapped page 또한, anonymous page처럼 Lazy Loading 되어야 하며,

vm_alloc_page_with_initializer( ) 또는 vm_alloc_page( )를 사용하여 페이지 개체를 만들 수 있다.

void munmap (void *addr);

munmap 함수는 지정된 주소 범위 addr에 대한 매핑을 해제한다. 

해당 가상 주소는 아직 매핑 해제되지 않은 동일한 프로세스가 mmap 함수 호출을 통해 반환한 가상 주소여야 한다.

모든 매핑은 프로세스가 종료할 때 암묵적으로 매핑 해제된다.

매핑이 해제되면 프로세스에 의해 쓰인 모든 페이지는 파일에 다시 기록되어야 한다.

그런 다음 해당 페이지들은 프로세스의 가상 페이지 목록에서 제거되어야 한다.

파일을 닫거나 제거해도 매핑은 해제되지 않는다. 일단 만들어진 매핑은 munmap이 호출되거나 프로세스가 종료될 때까지 유효하다.

파일에 대한 별도의 독립적인 참조를 얻기 위해 file_reopen( ) 함수를 사용해야 한다.

 

두 개 이상의 프로세스가 동일한 파일을 매핑하는 경우, Unix는 두 매핑이 동일한 물리적 페이지를 공유하도록 함으로써 이것을 해결한다.

mmap 시스템 콜은 페이지 공유 여부를 특정하는 인자를 갖고 있다.

필요에 따라 vm/vm.c에서 vm_file_init 및 vm_file_initializer( )를 수정할 필요가 있다.

void vm_file_init (void);

file-backed page 하위 시스템을 초기화한다. 이 함수는 file backed page와 관련된 모든 것을 설정할 수 있다.

bool file_backed_initializer (struct page *page, enum vm_type type, void *kva);

file-backed page를 초기화한다. page-> operations의 file-backed page에 대한 핸들러를 설정한다.

메모리를 백업하는 파일과 같은 페이지 구조체의 일부 정보를 업데이트할 수 있다.

static void file_backed_destroy (struct page *page);

관련 파일을 닫아서 file-backed page를 삭제한다. 콘텐츠가 dirty 상태라면 파일에 변경된 내용을 다시 작성해야 한다.

이 함수에서 페이지 구조체를 해제할 필요가 없다. file_backed_destroy( ) 함수 호출자(caller)가 처리하면 된다.

Comments