[운체] 오늘의 삽질 - 0807

방법이있지·2025년 8월 7일
post-thumbnail

Stack Growth

  • 기존 Project 2의 스택 영역은 딱 한 페이지 (4KB)
  • 이제 스택 영역이 꽉 차면, 추가로 페이지를 할당
  • 스택 포인터의 값 확인하기
    • 시스템 콜: syscall_handler()로 전달된 struct intr_frame의 필드 rsp
    • 페이지 폴트: page_fault()로 전달된 struct intr_frame의 피드 rsp
    • 커널 내에서 페이지 폴트가 발생할 시: 기본적으로 undefined. 사용자 -> 커널 전환 시 struct threadrsp를 저장한다거나 해야 함.
      • struct threaduintptr_t형 필드 하나 추가 후, 시스템 콜 발생시 호출되는 syscall_handler에서 저장하는 식으로 구현할 수 있을 듯
      • 일단 테스트 케이스에선 system call 내부에서 stack growth가 잘 처리되는지만 확인하므로, 다른 경우는 일단 수정하지 않아도 될듯. 어셈블리어를 고치는 건 너무 빡세기도 하고.

vm_try_handle_fault

  • spt_find_page == NULL일 때, stack growth를 시도할 수 있는지 여부 확인
  • 조건 1 스택 포인터 > page fault 발생 주소 >= 스택 포인터 - 8)인 경우
    • 즉, 스택 포인터에서 8바이트 이내에 접근하는 경우.
    • x86 PUSH 명령은, 스택 포인터(rsp) 조정 전 접근 권한을 먼저 확인
    • rsp-8에 접근할 때, 아직 메모리가 존재하지 않으면 page fault
    • rsp: user mode인 경우 f -> rsp에서, kernel mode인 경우 앞서 struct thread에 저장한 필드에서 확인. user 변수가 1인지 0인지로 확인할 것.
  • 조건 2 page fault 발생 주소 >= USER_STACK - 1 << 20
    • 즉, 스택 최대크기를 초과하지 않는 경우.
    • 스택의 최대크기는 1메가바이트, 이를 넘는 범위에서 페이지 폴트 발생 시 실패 처리
  • 조건 1, 2 모두 만족하는 경우, vm_stack_growth 호출
    • 성공 시, spt_find_page로 돌아가 재시도

vm_stack_growth

  • 스택에 새로운 anonymous page를 할당해 크기 확장
static void vm_stack_growth(void *addr UNUSED)
  • vm_alloc_page_with_initializer
  • 단, fault 발생한 주소를 페이지 정렬 맞게 내림한 뒤, 필요한 만큼 반복문으로 할당
    • rsp를 수동으로 낮춘 경우 1페이지 이상을 할당해야 할 수도 있음
    • 초기값을 pg_round_down(addr)로 하고, 주소를 PGSIZE값만큼 증가
    • vm_alloc_page_with_initializer가 실패할 때까지 반복문 돌리기
profile
뭔가 만드는 걸 좋아하는 개발자 지망생입니다. 프로야구단 LG 트윈스를 응원하고 있습니다.

0개의 댓글