본문 바로가기

정글캠프-WIL/핀토스

pintos - vm [setup_stack] 초기 스택 영역 메모리 관리 대상 추가

https://gyumingomin.tistory.com/95

 

pintos - vm_do_claim_page 구현

https://gyumingomin.tistory.com/94 vm - Page Fault 구현https://gyumingomin.tistory.com/92 Pintos - vm [페이지 할당 초기화 과정을 위한 흐름도]https://gyumingomin.tistory.com/91 Pintos - SPT(Supplemental Page Table)와 Hash TableSPT(Supplem

gyumingomin.tistory.com

여기서 vm_do_claim_page가 무엇인지 이해하고 오는 것을 추천드립니다.

1. setup_stack

setup_stack(struct intr_frame *if_)

위 코드는 유저 프로그램 방식의 초기 user stack 1페이지를 미리 물리 메모리에 올려서 연결하는 코드였다.
1. 유저 프로그램이 쓸 물리 프레임 1개를 유저풀에서 가져와 내용을 0으로 초기화하고
2. 가상주소와 물리프레임을 연결하는 작업을 한 후
성공하면 초기 스택 포인터를 스택 맨 위로 두고, 실패하면 다시 반환하는 작업이었다.

접은글 : setup_stack 구현

먼저 유저 프로그램 방식과 비교하기 전에 미리 봐야 할 코드를 학습하고자 한다.

ⓐ. vm_alloc_page

위 코드는 매크로 때문에 실제로 아래와 같이 바뀜

vm_alloc_page_with_initializer(
    VM_ANON | VM_MARKER_0,
    stack_bottom,
    true,
    NULL,
    NULL
);

stack_bottom 주소에 anonymous page 하나를 만들고 이 페이지는 writable=true로 등록하라는 의미

⑴. anonymous page를 하나 만드는 이유

- 여기서 stack은 파일과 연결된 데이터가 아님

  - 실행파일(ELF) 안에 실제 내용이 없음

  - 실행 중 동적으로 생성 됨

  - swap out되면 swap disk에 저장해야 함

⑵. VM_MARKER_0을 추가하는 이유

- VM_ANON만으로는 "익명 페이지" 까지만 알 수 있다.

- VM_MARKER_0을 추가하면 "익명 페이지인데 stack 용도로 사용되는 페이지" 까지 표현 가능

⑶. writable인 이유

스택에 저장되는 값
지역변수
함수 인자
return address
saved rbp
임시 값

계속 쓰고 읽어야 하므로 stack page는 반드시 writable이어야 함.

void foo() {
    int a = 10;
}

이 코드는 스택에 a = 10을 쓰는 거라 writable이 아니면 바로 page fault / 권한 위반이 발생

만약 위의 내용이 이해가 가지 않는다면,

https://gyumingomin.tistory.com/94

 

vm - Page Fault 구현

https://gyumingomin.tistory.com/92 Pintos - vm [페이지 할당 초기화 과정을 위한 흐름도]https://gyumingomin.tistory.com/91 Pintos - SPT(Supplemental Page Table)와 Hash TableSPT(Supplemental Page Table)에서 hash table을 왜 쓸까?Pintos V

gyumingomin.tistory.com

위 주소의 Stack 예시를 보시면 됩니다.

⑷. User Program과 차이

- user program

  - 처음부터 물리 프레임 할당

  - install_page로 바로 PML4 연결

  - stack 1 페이지 즉시 사용 가능

- vm

  - 결국 처음부터 물리 프레임을 할당하는 것은 같지만, vm 시스템의 관리 대상이 됨

  - 이 말의 의미는 vm_claim_page로 얻은 페이지가 swap_out의 대상이 될 수가 있게 됨

  - 즉, page fault / eviction / destroy 흐름에서 일관되게 처리 가능해짐

ⓑ. vm_claim_page

접은글 : vm_claim_page 구현

1. 현재 프로세스의 spt를 가져와서 va를 page 단위 주소로 정렬해 spt_find_page()로 page를 찾는데, 없으면 실패를 반환한다.
2. page가 존재하면 vm_do_claim_page()를 호출해 PML4 매핑 및 swap_in까지 수행해 실제 물리프레임을 연결하고 메모리에 올리는 작업을 수행한다.
참고
초기 page stack도 eviction 대상이 될 수 있는걸까?
일반적으로는 현재 실행 중인 stack은 거의 항상 최근에 접근되기 때문에 victim으로 잘 안뽑힘
But!
예를 들어 깊은 재귀 후 복귀일 경우
예전에 사용했던 아래쪽 stack page들은 rsp와 멀어지고 최근 접근이 안되는 상태가 가능함
결국 제일 위에 있는 main stack frame이 accessed bit가 꺼져있다면 swap out 후보가 되고
swap disk로 빠질 수 있는 상태가 생길 경우가 존재