[WEEK 11] PintOS - Project 3: Virtual Memory (Memory Mapped File)

신호정 벨로그·2021년 10월 20일
0

Today I Learned

목록 보기
61/89

Memory Mapped File

Memory Mapped File 개요

현재의 PintOS는 mmap()과 munmap() 함수가 구현되어 있지 않기 때문에 요구 페이징에 의해 파일 데이터를 메모리로 로드하는 mmap() 함수와 파일 맵핑을 제거하는 munmap() 함수를 구현해야 한다.

  1. Treat file I/O as routine memory access by mapping a disk block to a page in memory.

파일의 입출력을 페이지에 존재하는 디스크 블록에 맵핑에 의한 메모리 접근으로 생각한다.

  1. A file is initially read using demand paging.

파일은 요구 페이징에 의해 가장 먼저 읽힌다.

  1. Simplifies file access by treating as ordinary memory accesses.

파일에 대한 접근을 read()나 write() 시스템 콜이 아닌 메모리를 통한 파일 입출력으로 생각한다.

  1. Also allows several processes to map the same file allowing the pages in memory to be shared.

여러 프로세스가 메모리의 페이지들을 공유하여 같은 파일을 사용할 수 있도록 한다.

Memory-Mapped Files

기본적인 메커니즘은 프로세스 A와 프로세스 B의 가상 메모리에서 물리 메모리에 접근하여 같은 파일을 사용한다. (추측)

프로세스 1의 공유 메모리와 프로세스 2의 공유 메모리를 사용하여 memory-mapped file을 생성한다. (추측)

Memory-Mapped I/O

  1. To allow more convenient access to I/O devices, many computer architectures provide memory-mapped I/O.

입출력 장치에 보다 편리한 접근을 가능하기 위해 많은 컴퓨터 시스템 설계자들은 메모리-맵핑 입출력을 제공한다.

  1. In this case, ranges of memory addresses are set aside and are mapped to the device registers.

이러한 경우 메모리 주소들이 준비되어야 한다.

  1. Read and writes to these memory addresses cause the data to be transferred to and from the device registers.

장치 레지스터로부터 데이터가 전송되어야 하기 때문에 메모리 주소들을 읽고 쓴다.

  1. This method is appropriate for devices that have fast response times.

빠른 응답 시간을 필요로 하는 장치들에 사용하기 적합하다.

Memory-Mapped File 개요

  1. mmap() 구현: mapid_t mmap(int fd, void *addr)
  • fd: 프로세스의 가상 주소공간에 맵핑할 파일

  • addr: 맵핑을 시작할 주소 (페이지 단위 정렬)

  • 성공 시 mapping id를 리턴하고, 실패 시 에러코드(-1)을 리턴한다.

  • 요구 페이징에 의해 파일 데이터를 메모리로 로드한다.

  1. munmap() 구현: void munmap(mapid_t mapping)
  • mmap()의 리턴 값을 통해 파일 맵핑을 제거한다.

Memory-Mapped File

프로세스 주소공간에 파일을 맵핑한다.

read/write 시스템 콜을 사용하는 대신 메모리 접근 함수(load/store)을 통해 파일을 접근한다.

파일 맵핑 메커니즘

mmap(int fd, void *addr)

  1. vm_entry를 생성한다.

  2. vm_entry를 hash_insert()하여 해시 테이블(thread 구조체의 vm)에 삽입한다.

  3. 인자로 입력된 addr로 프로세스 가상 주소로부터 요구 페이징한다.

맵핑된 파일의 관리

thread 구조체에 mmap_list라는 멤버를 추가하여 mmap_file 구조체의 정보를 포함하고 vm_entry를 통해 프로세스 주소공간에 접근하여 블록 장치의 메모리-맵핑 파일들을 사용한다.

mmap_file 자료구조 추가

struct mmap_file 구조체를 생성하여 맵핑된 파일의 정보를 저장한다.

  1. mapid: mmap() 성공 시 리턴된 mapping id

  2. file: 맵핑하는 파일의 파일 오브젝트

  3. elem: mmap_file들의 리스트 연결을 위한 구조체

  4. vme_list: mmap_file에 해당하는 모든 vm_entry들의 리스트

vm_entry의 리스트 구조

thread 구조체의 해시 테이블 vm에서는 vm_entry의 elem 필드를 사용한다.

mmap_file의 리스트 헤드 vme_list는 vm_entry의 mmap_elem 필드를 사용한다.

해시 테이블 vm은 buckets 필드를 가지며 vm_entry가 어떤 bucket에 저장되어 있는지 나타낸다.

munmap() 동작

  1. mmap_list에서 해제할 mmap_file을 검색한다.

  2. vme_list 내의 모든 vm_entry를 해제한다.

  3. mmap_file을 해제한다.

munmap() 함수는 mmap_list에서 해제할 mmap_file을 검색하여 vme_list 내의 모든 vm_entry를 해제하고 마지막으로 mmap_file을 해제한다.

mmap() 함수는 인자로 입력 받은 addr가 유효한지 확인하고 file_reopen()을 실행하여 mapid를 할당한다. mmap_file을 생성 및 초기화하고 vm_entry를 생성 및 초기화한다. 성공 시 mapid를 반환한다.

munmap() 함수는 mmap_list를 순회하여 인자로 입력 받은 mapping id와 일치하는지 확인한다. 일치하는 vm_entry를 제거하고 페이지 테이블 엔트리를 제거한다. 마지막으로 mmap_file을 제거하고 file_close() 한다.

int mmap(inf fd, void *addr) 구현

  • fd: 프로세스의 가상 주소공간에 맵핑할 파일

  • addr: 맵핑을 시작할 주소 (페이지 단위 정렬)

  • 성공 시 mapping id를 리턴, 실패 시 에러코드(-1) 리턴

  • 요구 페이징에 의해 파일 데이터를 메모리로 로드

void munmap(int mapping) 구현

  • mmap_list 내에서 mapping에 해당하는 mapid를 갖는 모든 vm_entry를 해제

  • 인자로 넘겨진 mapping 값이 CLOSE_ALL인 경우 모든 파일 맵핑을 제거

  • 페이지 테이블에서 엔트리 제거

  • 맵핑 제거 시 do_munmap() 함수 호출

void do_munmap(struct mmap_file *mmap_file) 구현

  • mmap_file의 vme_list에 연결된 모든 vm_entry들을 제거

  • 페이지 테이블 엔트리 제거

  • vm_entry 가리키는 가상주소에 대한 물리 페이지가 존재하고, dirty하면 디스크에 메모리 내용을 기록

파일 맵핑 요구 페이징 지원을 위한 페이지 폴트 핸들러 수정

handle_mm_fault()를 통해 페이지 할당 여부를 확인 vm_entry 타입을 확인한다. VM_BI 파일일 경우 파일에서 메모리로 데이터를 로드하고 페이지 테이블을 셋업한다.

vm_entry 타입이 VM_FILE일 경우 데이터를 로드할 수 있도록 handle_mm_fault()를 수정한다.

process_exit() 함수 수정

프로세스가 종료될 시 mmap_list 내에서 mapping에 해당하는 mapid를 갖는 모든 vm_entry을 해제를 제거하도록 수정한다.

0개의 댓글