본문 바로가기
정글/pintos

[Project3] Virtual Memory(4) - Stack Growth

by 위대한초밥V 2023. 6. 21.

프로젝트 2에서 스택은 USER_STACK에서 시작하는 한 페이지로 제한되어있으며, 해당 사이즈 내에서만 프로그램이 실행될 수 있었다.

 

이번 과제에서는 스택이 현재 크기 이상으로 커지면, 필요에 따라 페이지를 추가 할당한다.(= 동적 할당)

이때 추가 페이지 할당은 스택 접근으로 보이는 경우에만 할당한다. 스택 접근과 다른 접근을 구분하는 방법을 고민해야 한다.

 

사용자 프로그램이 스택 포인터 아래에서 쓰기 작업을 수행하면 버그가 발생한다.

일반적인 OS는 “Signal”(여기서는 쓰기가 신호가 된다!)을 전달하기 위해 언제든지 프로세스를 중단할 수 있다. 이 중단으로 인해 스택 데이터는 수정될 수 있다.

X86-64 아키텍처의 PUSH 명령은 스택 포인터를 조정하기 전에 접근 권한을 확인한다. 만약 스택 포인터 8byte 아래를 접근한다면 page fault가 발생할 수 있다.

이처럼 사용자 프로그램의 스택 관련 작업을 하려면, 사용자 프로그램의 현재 스택 포인터 값을 알아야 한다. 시스템 호출이나 사용자 프로그램에서 나온 page fault는 syscall_handler() 또는 page_fault() 로 전달된 struct intr_frame의 rsp 멤버에서 검색할 수 있다.

 

만약 유효하지 않은 메모리 접근을 page fault만 고려한다면, kernel에서 page fault가 발생한 경우를 고려해야 한다. 프로세서는 일반적으로 예외처리나 인터럽트 발생 시, user -> kernel 모드로 전환될 때 스택 포인터를 저장한다. 이를 통해 커널 모드에서 예외 처리나 커널 코드를 수행하는 동안 새로운 스택을 사용하고, 처리가 완료되면 원래 상태를 복원한다.

따라서 page_fault() 함수에서 struct intr_frame 구조체를 통해 rsp(스택 포인터)를 읽는 것이 정의되지 않은 값을 반환하므로,

user 모드에서 kernel 모드로 처음 전환될 때, thread 구조체에 rsp를 저장하는 방법 등을 사용해야 한다.

 

stack growth 기능 구현 과정은 다음과 같다.

  1. vm/vm.c에서 vm_try_handle_fault 를 수정하여 스택 증가를 식별한다.
  2. 스택 증가를 식별하고 vm/vm.c 에서 vm_stack_growth 를 호출하여 스택을 증가시킨다.
  3. vm_stack_growth 를 구현한다.

 

bool vm_try_handle_fault (struct intr_frame f, void addr, bool user, bool write, bool not_present); 

page fault 예외를 처리할 때, userprog/exception.c 에서 page_fault 함수에서 호출된다. 이 함수는 page fault가 발생한 상황에서 스택의 크기를 늘릴 수 있을 지 확인해야 한다.

스택 크기를 늘릴 수 있는 상황은 다음과 같다.

  • 주소가 사용자 영역에 속하는가 → 스택 확장은 사용자 프로그램 실행 중에 사용된다.
  • 쓰기 작업으로 인해 페이지 폴트가 발생한 것인가 → 스택 확장은 데이터를 스택에 푸시(push)하는 작업같은 쓰기 작업에서 발생한다.
  • 페이지가 매핑되지 않았는가 → 스택 확장을 하려면 스택 크기를 넘어서는 주소에 대한 페이지 매핑이 되어야 한다.

 

void vm_stack_growth (void *addr); 

addr이 더이상 faulted address가 아니기 때문에, 하나 이상의 anonymous page를 할당하여 스택 사이즈를 늘린다. 할당을 처리할 때 PGSIZE에 대한 addr 을 반올림해야 한다.

대부분의 OS는 스택 사이즈를 제한한다. 일부 OS에서는 사용자가 사이즈를 조정할 수 있지만(ex. UNIX 시스템의 unlimit 명령) 많은 GNU/Linux 시스템에서 기본 제한은 8MB이다. 이 프로젝트에서는 스택 크기는 최대 1MB로 제한한다.

 

여기까지하면 모든 stack-growth 테스트 케이스가 통과되어야 한다.

 

+) Stack에 대해 더 알아보자.

- CSAPP 3.7 프로시저 

- https://it-eldorado.tistory.com/37

 

반응형