거북이의 쉼터

(2022.03.06) Anonymous Page 가이드라인 (2) 본문

코딩 삽질/KAIST PINTOS (CS330)

(2022.03.06) Anonymous Page 가이드라인 (2)

onlim 2022. 3. 6. 18:55

왜 자도 잔 것 같지가 않지... 글이 안 써진다.

 

지금 구현되지 않은 것들에 대해 생각이 너무 깊어서 구현을 하려고 해도, 구현이 안된 것들이 발목을 잡는다. 그래서 몇 가지 규칙을 잡아놓고 구현을 하도록 한다.

 

  • 메모리 누수는 되도록 신경 쓰지 않는다. 특히 struct frame의 free 여부는 잊어버리자.
  • eviction과 관련되는 코드는 TODO 형태로 주석만 남겨놓고 구현하지 않는다.
  • VM_FILE 종류는 신경 쓰지 않는다.
  • Extra 프로젝트인 COW는 나중에 코드를 전부 뜯어고치는 한이 있더라도 신경쓰지 않는다.

그럼 시작하자.

 

매뉴얼의 남은 부분은 fork의 정상 작동을 위해 일반 페이지 테이블(pt)과 spt를 제대로 복사해야 하는 것과, 프로세스가 종료할 때 들고있는 자원을 반환하는 것이다. 우선 복사하는 함수인 supplemental_page_table_copy 부터 살펴보자.

 

spt를 복사하기 위해서는 spt가 들고 있는 각각의 struct page를 복사할 필요가 있다. 또한 해당 struct page 마다 연동된 frame이 있을 수 있으므로, frame의 할당과 내용의 복사 또한 이루어져야 한다. 지금까지 고려했던 VM_UNINIT과 VM_ANON 타입의 페이지만 우선적으로 고려하면 다음과 같다.

 

  • VM_UNINIT : 원본과 init 과정이 똑같이 전개만 되도록 설정하면 된다. 복사할 페이지에서 갖고 있는 인자를 복사해서 vm_alloc_page_with_initializer로 spt에 넣어주도록 한다.
  • 물리 메모리 상에 프레임이 존재하는 VM_ANON : 원본 페이지와 연동된 프레임의 주소를 구할 수 있으므로, memcpy를 사용해 복사하도록 한다.

eviction이 구현되고 나면 물리 메모리 상에 프레임이 존재하지 않는 VM_ANON 페이지도 생길 것이며, 이는 swap_disk에서 복사를 한 뒤에 연동해야 할 부분이므로 일단 넘기자.  

 

여기까지 구현하면 spt는 다 된 것 같다. 문제는 pt의 access와 dirty bit 또한 같이 맞춰주어야 하는데, spt를 복사하는 함수 단계에서 부모의 pt에 접근할 방법이 마땅치 않다는 것이다. 때문에 spt 구조체에 현재 어떤 thread가 해당 spt를 소유하는지를 같이 저장하도록 변경하고, spt 구조체에서 thread 포인터를 통해 pml4를 찾도록 한다.

 

다음으로 supplemental_page_table_kill이다. 해당 함수가 불리는 시점은 process_exit 등의 이유로 process_cleanup이 호출되었을 때이다. 그때까지 spt가 갖고 있던 자원을 모두 해제해주어야 하며, 연결된 frame은 일반 pt를 정리할 때 free되므로 신경쓰지 않아도 된다. 즉 순수히 struct page에서 들고있었던 자원을 반환하도록 하는 것이 해당 함수이다. 해당 함수를 구현할 때 각 엔트리인 struct page의 종류별로 자원을 해제해주어야 할 방법이 다르다. 이를 위해 pintos에서 destroy 매크로를 각 종류별로 다른 destroy 함수를 호출하도록 지정함으로써, 일괄적으로 처리할 수 있도록 만들었다. VM_UNINIT과 VM_ANON에 해당하는 destory 함수를 구현하고, 이를 이용하여 supplemental_page_table_kill을 구현하면 끝이다.

 

사실 목적 자체는 단순한데 이 짧은 글 쓰는데 8시간이 걸렸다. 코드 자체도 계속 들여다 봐야 하고 고칠 곳, 아직은 신경쓰지 않아도 되는 부분 등을 다 고려하다 보니 시간이 미친듯이 빠르게 지나갔다. 다음 포스팅부터는 일단 고쳐야 하는 곳부터 시작해 구현해야 할 부분만 짚고 테스팅을 해보도록 하자.

Comments