[pintos] project3 - VM

bang·2023년 5월 23일
0

Stack Growth

기존

기존에는 스택이 USER_STACK에서 시작하는 단일 페이지로 4KB로 제한하여 실행했다. 이제부터는 stack growth를 통해 스택이 초과하면 필요에 따라 추가 페이지를 할당하여야 한다.

  • 추가 페이지 할당은 스택에 접근하는 경우에만 할당하여야 한다.
  • 스택에 접근하는 경우와 아닌 경우를 구분하여야 한다.

USER_PROGRAM은 스택 포인터(rsp) 아래를 사용할 경우 버그가 발생하였다.
-> 일반적인 실제 os가 스택의 데이터를 수정하는 시그널을 전달하기 위해 언제든지 프로세스를 중단할 수 있기 때문이다.

하지만 x86-64 push 명령어는 스택 포인터를 조정하기 전 접근 권한을 검사하므로 stack pointer 아래 8바이트에 대해 page fault를 발생시킬 수 있다.

USER_PROGRAME은 스택 포인터의 현재 값을 얻을 수 있어야 한다.

  • system call - syscall_handler()
  • page fault - page_fault()
    위 두 함수에 전달된 intr_framersp를 검색하면 된다.

USER모드에서 KERNEL모드로 전환 시 rsp를 struct thread에 저장하는 방법 등을 사용해야 한다.

수정사항

  1. vm_try_handle_fault를 수정하여 스택 증가를 확인한다.
  2. vm_stack_growht를 호출하여 스택을 증가시킨다.
  3. 하나 이상의 anonymous page를 할당하여 스택의 크기를 늘린다.
  4. addr은 fault주소에서 유효한 주소가 된다. page를 할당할 때 주소를 PGSIZE로 내린다.

    [!seealso]
    대부분의 OS에서 스택의 크기는 제한되어 있다. GNU/linux는 기본 제한은 8MB이고 우리가 사용하는 pintos의 경우 1MB로 제한되어있다.

rsp - 8바이트를 체크하는 이유

Memory Mapped Files

Memory Mapped Files이란?

메모리 맵 파일은 운영 체제에서 파일을 다루는 방법 중 하나이다. 물리 디스크 파일, 장치, 공유 메모리 객체와 같이 운영 체제에서 파일로 다루는 모든 대상에 대해서 사용 가능하며, 메모리 맵 파일을 통해 프로세스의 가상 메모리 주소 공간에 파일을 매핑한 뒤 가상 메모리 주소에 직접 접근하는 것으로 파일 읽기/쓰기를 대신한다.

read_bytes

read_bytes 변수는 do_mmap 함수의 매개변수인 length 값과 관련이 있다. length는 매핑하려는 메모리 영역의 크기를 나타낸다. read_bytes는 이 length 값으로 초기화되며, 매핑할 때까지 남은 읽기 바이트 수를 나타낸다.

zero bytes

변수 zero_bytes는 파일을 매핑할 때 메모리 페이지의 끝에 필요한 패딩 또는 "제로" 바이트의 양을 결정하기 위해 메모리 매핑 컨텍스트에서 사용됩니다.

파일을 메모리 매핑할 때 파일의 내용은 일반적으로 시스템의 메모리 페이지 크기인 고정 크기 페이지로 나뉩니다. 그러나 파일 크기가 페이지 크기의 정확한 배수가 아닐 수 있으므로 끝에 부분 페이지가 표시됩니다.

'zero_bytes' 변수는 마지막 메모리 페이지를 채우는 데 필요한 남은 바이트 수를 나타냅니다. 예상 페이지 크기를 유지하기 위해 메모리 페이지에서 0으로 설정해야 하는 바이트 수를 나타냅니다.

offset

offset 매개변수는 메모리 매핑 컨텍스트에서 매핑이 시작되어야 하는 파일 내의 시작 위치를 지정하는 데 사용됩니다.

파일을 메모리 매핑할 때 '오프셋'을 사용하면 메모리에 매핑할 파일 부분을 제어할 수 있습니다. 오프셋을 지정하여 전체 파일, 특정 범위를 매핑하거나 파일 내의 특정 위치에서 매핑을 시작하도록 선택할 수 있습니다.

Dirty Bit

Dirty bit은 해당 페이지가 변경되었는지 여부를 저장하는 비트이다. 페이지가 변경될 때마다 이 비트는 1이 되고, 디스크에 변경 내용을 기록하고 나면 해당 페이지의 dirty bit는 다시 0으로 초기화해야 한다. 즉, 변경하는 동안에 dirty bit가 1이 된다.

페이지 교체 정책에서 dirty bit이 1인 페이지는 디스크에 접근해 업데이트한 뒤 매핑을 해제해줘야 하기 때문에 비용이 비싸다. (디스크 한 번 갔다 와야 하니까). 따라서 페이지 교체 알고리즘은 dirty page 대신 변경되지 않은 상태인 깨끗한(?) 페이지를 내보내는 것을 선호한다. 이 경우는 그냥 swap out만 해주면 되니까.

Present Bit

해당 페이지가 물리 메모리에 매핑되어 있는지 아니면 swap out되었는지를 가리킨다. Swap in/out에서 더 다룰 것. present bit이 1이면 해당 페이지가 물리 메모리 어딘가에 매핑되어 있다는 말이며 0이면 디스크에 내려가(swap out)있다는 말이다. 이렇게 present bit이 0인, 물리 메모리에 존재하지 않는 페이지에 접근하는 과정이 file-backed page에서의 page fault이다.

실패 조건

  1. 매핑하는데 실패하면 NULL 반환
  2. fd로 열린 파일의 길이가 0바이트인 경우, mmapp에 대한 호출이 실패
  3. addr이 page-align 되지 않았거나
  4. 기존 매핑된 페이지 집합과 겹치는 경우 실패
  5. addr이 0이면 실패해야 함
  6. length가 0일 때도 실패해야 함
  7. 콘솔 및 입출력을 나타내는 파일은 매핑할 수 없음

0개의 댓글