Project_3 : Virtual Memory - Swap In/Out(1)
메모리 스와핑은 물리 메모리의 사용을 극대화하기 위한 메모리 회수 기술이다.
모든 메인 메모리 프레임이 할당되면 시스템은 사용자 프로그램의 메모리 할당 요청을 더 이상 처리할 수 없다.
한 가지 방법은 현재 사용되지 않는 메모리 프레임을 디스크로 스왑 아웃시키는 것이다.
이렇게 하면 메모리 자원을 해제하여 다른 응용 프로그램에서 사용할 수 있게 된다.
스와핑은 운영체제에 의해서 이루어진다.
시스템이 메모리가 부족함을 감지한 상태에서 메모리 할당 요청을 받으면 방출할 페이지를 선택한다.
이때, 메모리 프레임의 정확한 상태가 디스크로 복사된다.
방출을 위해 선택된 페이지는 anonymous page 혹은 file-backed page이다. 각 사례를 처리해야 한다.
프로세스가 스왑 아웃된 페이지에 접근하려고 하면, 운영체제는 메모리로 정확한 콘텐츠를 가져와 페이지를 복구한다.
모든 스와핑 연산은 명시적으로 호출되지 않고 함수 포인터로서 호출된다.
이들은 page_operations 구조체의 file_ops로, 각 페이지 이니셜라이저에 대한 연산으로 등록된다.
Anonymous Page
vm/anon.c의 anon_init과 anon_initializer를 수정해야 한다. anonymous page는 backing storage가 없다.
anonymous page의 스와핑을 지원하기 위해서 swap disk라고 불리는 임시 backing storage를 제공한다.
void vm_anon_init (void);
vm_anon_init( ) 함수는 swap disk를 설정해야 하고, swap disk의 사용 가능한 영역과 사용된 영역을 관리할 자료구조가 필요하다.
스왑 영역은 PGSIZE(4097 bytes, 4KB) 단위로 관리된다.
bool anon_initializer (struct page *page, enum vm_type type, void *kva);
anonymous page의 이니셜라이저 함수이다. 스와핑을 지원하기 위해서 anon_page에 대한 몇 가지 정보를 추가해야 한다.
vm/anon.c에서 anon_swap_in 및 anon_swap_out을 구현하여 anonymous page에 대한 스왑을 지원해야 한다.
페이지를 스왑 인하려면 스왑 아웃을 먼저 해야 하므로 anon_swap_in을 구현하기 전에 anon_swap_out을 먼저 구현하는 것이 좋다.
데이터 내용을 swap disk로 옮기고 그것을 안전하게 메모리로 가져와야 한다.
static bool anon_swap_in (struct page *page, void *kva);
anon_swap_in( ) 함수는 디스크에서 메모리로 데이터 내용을 읽어 swap disk에서 anonymous page를 스왑 한다.
데이터의 위치는 페이지가 스왑 아웃되었을 때, 페이지 구조체에 저장되어 있는 위치이다.
그리고 스왑 테이블을 업데이트해야 한다.
static bool anon_swap_out (struct page *page);
anon_swap_out( ) 함수는 메모리의 내용을 디스크로 복사하여 anonymous page를 swap disk로 스왑 한다.
먼저 스왑 테이블을 이용하여 디스크에서 사용 가능한 스왑 슬롯을 찾은 다음 데이터 페이지를 슬롯에 복사한다.
데이터의 위치는 페이지 구조체에 저장되어야 한다. swap disk에 사용 가능한 슬롯이 없으면 커널을 패닉 상태로 만들 수 있다.
File-Mapped Page
file-backed page의 내용은 파일에서 나오기 때문에, mmaped file을 backing store로 사용해야 한다.
즉, file-backed page를 방출하면 그 내용을 매핑된 파일에 다시 기록한다.
vm/file.c에 file_backed_swap_in( )과 file_backed_swap_out( )을 구현해야 한다.
설계에 따라 file_backed_init( )과 file_initializer( )를 수정할 수 있다.
static bool file_backed_swap_in (struct page *page, void *kva);
파일의 내용을 읽어 kva의 페이지를 스왑 인한다. 파일 시스템과 동기화해야 한다.
static bool file_backed_swap_out (struct page *page);
파일에 내용을 다시 기록하여 페이지를 스왑 아웃한다. 페이지가 dirty 상태인지 먼저 확인하는 것이 좋다.
dirty 상태가 아니라면 파일의 내용을 수정할 필요가 없다. 페이지를 스왑 아웃한 이후 해당 페이지의 dirty 비트를 해제해야 한다.