미소를뿌리는감자의 코딩
[Pintos_project3 (14)] vm_try_handle_fault, vm_stack_growth 본문
728x90
1. 개요
이번에 Stack Growth에 대해서 다루어 보려고 한다.
stack은 init으로 1개의 페이지를 먼저 초기화를 하고 시작한다.
하지만 1개의 페이지보다 더 많은 stack을 이용하려고 할 시, 어떻게 될 것인가?
이를 다루기 위한 것이 이번 단원의 목표이다.
따라서, page_fault가 일어났을 시, 이것이 일반적인 page fault인지 아니면, stack이 초과되어서 나는 page_fault인지 파악해야 한다.
만약에 spt에서 page를 찾을 수 없으면, false를 반환했던 것과 달리, 코드를 작성해 주어야 한다.
커널 모드에서 발생한 페이지 fault의 경우 sp가 저장되지 않는다.
따라서, 쓰레기 값이 저장되어 있을 수 있기 때문에 유저 모드에서 커널 모드로 전환 시, sp를 struct thread에 저장해 주어야 한다.
2. 본문
코드를 보면서 확인해 보자.
/** Project 3: Memory Management - Return true on success */
bool vm_try_handle_fault(struct intr_frame *f UNUSED, void *addr UNUSED, bool user UNUSED, bool write UNUSED, bool not_present UNUSED) {
struct supplemental_page_table *spt UNUSED = &thread_current()->spt;
struct page *page = spt_find_page(&thread_current()->spt, addr);
/* TODO: Validate the fault */
if (addr == NULL || is_kernel_vaddr(addr))
return false;
/** Project 3: Copy On Write (Extra) - 이전에 만들었던 페이지인데 swap out되어서 현재 spt에서 삭제하였을 때 stack_growth 대신 claim_page를 하기 위해 조건 분기 */
if (!page) {
/** Project 3: Stack Growth - stack growth로 처리할 수 있는 경우 */
/* stack pointer 아래 8바이트는 페이지 폴트 발생 & addr 위치를 USER_STACK에서 1MB로 제한 */
void *stack_pointer = user ? f->rsp : thread_current()->stack_pointer;
if (stack_pointer - 8 <= addr && addr >= STACK_LIMIT && addr <= USER_STACK) {
/* stack_pointer - 8 <= addr ; 스택 overflow가 맞는지 확인 sp' 8 byte 내에 있는 요청인지 확인
* addr >= STACK_LIMIT ; 스택이 시스템의 허용 범위를 초과하지 않는지 확인. 즉, 1MB를 초과하지 않는지 확인
* addr <= USER_STACK ; 스택은 USER_STACK에서 아래로 성장한다. 하지만, USER_STACK보다 위의 addr에 접근하는 건 잘못된 접근이므로 이를 확인하여 준다.
*/
vm_stack_growth(thread_current()->stack_bottom - PGSIZE); // vm의 stack의 제한을 늘림. 1 PAGE 만큼.
return true;
}
return false;
}
return vm_do_claim_page(page); // demand page 수행
}
추가적인 stack page를 할당하기에 앞서 확인해야하는 것이 3가지 있다. 이들 모두를 충족시켜야 한다.
- 스택이 초과되어서 난 page fault가 맞는지 확인한다. sp의 8 Byte이내에 addr가 있는 지 확인.
- 스택의 시스템의 허용 범위(STACK_LIMIT)을 초과하지 않는지 확인한다. stack이 부족하더라도, 시스템이 허용한 stack 할당 용량을 벗어나기 때문에 추가적인 스택 페이지를 할당할 수 없다.
- 스택은 USER_STACK에서 아래로 성장한다. 만약 USER_STACK보다 위에 있는 addr라면, 이는 스택 초과로 인한 page fault가 아니기 때문에, false를 반환한다.
/* Growing the stack. */
static void
vm_stack_growth (void *addr UNUSED) {
/* rsp 기준을 늘리기 */
bool success = false;
if (vm_alloc_page(VM_ANON | VM_MARKER_0, addr, true)) { // 현재 stack_bottom에서 1 PAGE만큼 아래의 주소에 대해서 vm_alloc_page를 시도.
success = vm_claim_page(addr);
if (success) {
thread_current()->stack_bottom -= PGSIZE;
}
}
}
3. 결과
3개의 테스트가 더 통과했음을 할 수 있다.
728x90
'정글 일지' 카테고리의 다른 글
[Pintos_project3 (16)] do_munmap, file_backed_destroy (0) | 2024.12.03 |
---|---|
[Pintos_project3 (15)] do_mmap (0) | 2024.12.03 |
[Pintos_project3 (13)] uninit_destory, anon_destory (0) | 2024.12.02 |
[Pintos_project3 (12)] supplemental_page_table_copy, supplemental_page_table_kill (0) | 2024.12.02 |
[Pintos_project3 (11)] vm_try_handle_fault (0) | 2024.12.02 |