Krafton Jungle/5. PintOS

[PintOS 5주차] Day 3

munsik22 2025. 6. 7. 14:13

Swap In/Out #

  • Memory swapping은 물리 메모리의 사용을 최대화시키기 위한 메모리 reclamation 기법이다.
    • 메인 메모리의 프레임이 할당되면, 시스템은 더 이상 유저 프로그램으로부터의 메모리 할당 요청을 다룰 수 없다.
    • 한 가지 해결법은 현재 디스크에서 사용되지 않는 메모리 프레임을 swap out하는 것이다.
  • Swapping은 OS에 의해 행해진다.
    • 시스템이 메모리의 부족한 상태에서 메모리 할당 요청을 받는다면, swap disk로 내쫓을 하나의 페이지를 고른다.
    • 메모리 프레임의 상태를 동일하게 디스크에 복사한다(swap out).
    • 프로세스가 swap out된 페이지에 접근하려고 시도할 때, OS는 메모리에 (디스크에 복사했던) 동일한 컨텐츠를 가져옴으로써 페이지를 복구한다.
  • 내쫓기기로 결정된 페이지는 anon page 또는 file page가 될 것이다. 각각의 경우에 대해 다뤄야 한다.
  • 모든 swapping 함수들은 명시적으로 호출되지 않고, 함수 포인터로서 호출된다.
    • 이 함수들은 struct page_operations file_ops의 멤버로, 각 페이지의 초기화 함수의 동작을 통해 등록된다.

Anonymous Page

vm/anon.c에서 vm_anon_initanon_initializer를 수정해야 한다: Anon page는 backing용 저장소를 가지지 않는다. Anon page의 swapping을 위해서 swap disk라고 불리는 임시 backing용 저장소가 제공된다. Anon page의 swap을 구현하기 위해 swap disk를 이용해야 할 것이다.

void vm_anon_init (void);
  • Swap disk를 설정해야 한다.
    • 스왑 디스크 내에서 free되거나 할당된 영역을 관리하기 위한 구조체가 필요할 것이다.
    • Swap 영역은 또한 PGSIZE(4KB) 단위로 관리될 것이다.
bool anon_initializer (struct page *page, enum vm_type type, void *kva);
  • Anon page를 위한 초기화 함수다.
    • Anon page의 swap을 지원하기 위한 정보들을 anon_page에 추가해야 한다.

Anon pages의 swapping을 위해서, anon.c에서 anon_swap_in과 anon_swap_out을 구현해야 한다: 페이지가 swap되기 위해서는 swap out되야 하기 때문에, anon_swap_in을 구현하기 전에 anon_swap_out을 먼저 구현해야 할 것이다. 데이터 컨텐츠를 swap disk로 옮기고, 다시 안전하게 메모리로 가져와야 한다.

static bool anon_swap_in (struct page *page, void *kva);
  • 데이터 컨텐츠를 디스크에서 메모리로 read함으로써 swap disk에서부터 anon page를 swap in한다.
    • 페이지가 swap out 될 때 swap disk는 struct page 내에 저장되어야 한다.
    • Swap table을 업데이트해야한다. (참고)
static bool anon_swap_out (struct page *page);
  • 메모리에서 디스크로 컨텐츠를 복사함으로써 anon page를 swap disk로 swap out한다.
    • 먼저, 스왑 테이블을 사용해 free 상태의 swap slot을 찾고, 슬롯에 페이지의 데이터를 복사한다.
    • 데이터의 위치는 struct page 안에 저장되어야 한다.
    • 디스크에 free slot이 없다면, 커널 패닉을 시킬 수 있다.

File-Mapped Page

File-backed page의 컨텐츠는 파일에서부터 온 것이기 때문에, mmap된 파일은 backing용 저장소로 사용되어야 한다. 즉, file-backed page를 내쫓는 것은 map되었던 write back하는 것이다. vm/file.c에서 file_backed_swap_in, file_backed_swap_out을 구현해야 한다. 설계에 따라 file_backed_initfile_initializer를 수정할 수도 있다.

static bool file_backed_swap_in (struct page *page, void *kva);
  • 파일에서부터 컨텐츠를 read함으로써 kva에 있는 페이지를 swap in한다.
    • 파일 시스템과 동기화해야 한다.
static bool file_backed_swap_out (struct page *page);
  • 파일에 컨텐츠를 write back함으로써 페이지를 swap out한다.
    • 먼저 페이지가 dirty인지 확인해야 할 것이다.
    • Dirty하지 않다면 파일의 컨텐츠를 수정할 필요가 없다.
    • 페이지를 swap out하고 나서 페이지의 dirty bit를 0으로 설정해야 한다.

Managing swap partition

  • Swap partition은 swap slot 단위(4KB)마다 관리된다.
    • Swap bitmap(메모리의 전역변수)를 사용해 swap partition을 유지할 수 있다.
    • Free slot을 위한 비트맵을 탐색해야 한다.
    • 시스템이 터지면 swap bitmap에서는 어떤 일이 생길까?


Swapping 구현

Swap slot은 비트맵을 사용해서 관리하는 것으로 구현했다. (참고)

struct bitmap *swap_slot;
struct anon_page {
    size_t slot_idx;
};
void
vm_anon_init (void) {
	/* TODO: Set up the swap_disk. */
	swap_disk = disk_get(1, 1);
    size_t swap_slot_cnt = disk_size(swap_disk) / SWAP_SLOTS_CNT;
    swap_slot = bitmap_create(swap_slot_cnt);
}
bool
anon_initializer (struct page *page, enum vm_type type, void *kva) {
	/* Set up the handler */
	page->operations = &anon_ops;

	struct anon_page *anon_page = &page->anon;
	anon_page->slot_idx = BITMAP_ERROR;
    return true;
}