본문 바로가기
OS/Pintos P.J_3

Pintos project3_Swap In/Out

by Success T.H.I.E.F 2022. 1. 25.

Swap In/Out

Memorry swapping은 사용가능한 물리 메모리를 최대화 하기위한 교정과정이다.

메인메모리의 frame이 모두 할당되면 시스템은 더이상 유저프로그램이 메모리 할당을 요구해도 들어줄 수 없다. 

이러한 문제의 해결책으로 현재 디스크에서 사용하지 않는 memory frame들을 교체하는 것이다.

 

스와핑은 OS가 하는 일이다. 시스템이 메모리 부족을 감지하고 메모리 할당요구가 들어왔을때 디스크로 방출시킬 페이지를 선택한다. 

 

그러면 방출될 메모리 프레임의 상태가 디스크로 복사된다. 프로세스가 방출된 page에 접근을 재요구하면 OS는 해당 page를 회복시키는데 이때 디스크에 복사해둔 content를 메모리로 돌려놓는다.

 

방출될 페이지는 anonymous page 이거나 file-backed page이다 이 각각에 대해 이번에 다루어 볼 것이다.

 

모든 스와핑 작업은 함수를 직접 호출하는 것이 아니라 pointer 형식으로 function을 호출하며 이들은 

page_operations 구조체와 file_ops 구조체의 멤버로 들어가 있다. 이것들은 각 페이지의 초기화 작업에 들어간다.

Anonymous Page

Anonymouse page는 어떠한 백업 strage도 가지고 있지 않다. anonymous page의 swapping을 보조하기 위해 swap disk라 부르는 임시 저장소를 제공하므로 이걸 이용해 anonymous page의 swap을 구현해 보자

 

수정할 함수는 vm/anon.c의 vm_anon_init 과 anon_initializer 이다.

vm_anon_init & anon_initializer 

/* Initialize the data for anonymous pages */
void
vm_anon_init (void) {
	/* TODO: Set up the swap_disk. */
	swap_disk = disk_get(1, 1); 
	size_t swap_size = disk_size(swap_disk) / SECTORS_PER_PAGE;
	swap_table = bitmap_create(swap_size);
}

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;
}
더보기

In this function, you need to set up the swap disk. You will also need a data structure to manage free and used areas in the swap disk. The swap area will be also managed at the granularity of PGSIZE (4096 bytes)

swap_table은 bitmap 구조체 변수이다. bitmap 구조체는 bits의 배열로 각 0과 1로 표현된다. 보통 비트맵은 자원의 사용율을 추적하는데 사용된다. 만약 자원이 사용중이면 비트맵에 TRUE로 표현된다. 

스왑테이블은 이를 이용 사용중이거나 사용할 수 있는 swap slot을 관리하는 테이블이다.

anon_swap_in & out

/* Swap in the page by read contents from the swap disk. */
static bool
anon_swap_in (struct page *page, void *kva) {
	struct anon_page *anon_page = &page->anon;
	int page_no = anon_page->swap_index;

	if (bitmap_test(swap_table, page_no) == false)
	{
		return false;
	}

	for (int i = 0; i < SECTORS_PER_PAGE; ++i)
	{
		disk_read(swap_disk, page_no * SECTORS_PER_PAGE + i, kva + DISK_SECTOR_SIZE * i);
	}

	bitmap_set(swap_table, page_no, false);

	return true;
}


/* Swap out the page by writing contents to the swap disk. */
static bool
anon_swap_out (struct page *page) {
	struct anon_page *anon_page = &page->anon;
	int page_no = bitmap_scan(swap_table, 0, 1, false);

	if (page_no == BITMAP_ERROR)
	{
		return false;
	}

	for (int i = 0; i < SECTORS_PER_PAGE; ++i)
	{
		disk_write(swap_disk, page_no * SECTORS_PER_PAGE + i, page->va + DISK_SECTOR_SIZE * i);
	}

	bitmap_set(swap_table, page_no, true);
	pml4_clear_page(thread_current()->pml4, page->va);

	anon_page->swap_index = page_no;

	return true;
}

 

 

file_backed_swap_in & out

파일 백 페이지는 파일에서 가져오기 떄문에 mmaped 파일을 백업 저장소로 사용한다 즉 파일 백 페이지를 제거하면 매핑된 파일에 다시 기록된다.

/* Swap in the page by read contents from the file. */
static bool
file_backed_swap_in (struct page *page, void *kva) {
	struct file_page *file_page UNUSED = &page->file;
	if (page == NULL)
		return false;

	struct container *aux = (struct container *)page->uninit.aux;

	struct file *file = aux->file;
	off_t offset = aux->offset;
	size_t page_read_bytes = aux->page_read_bytes;
	size_t page_zero_bytes = PGSIZE - page_read_bytes;

	file_seek(file, offset);

	if (file_read(file, kva, page_read_bytes) != (int)page_read_bytes)
	{
		// palloc_free_page (kva);
		return false;
	}

	memset(kva + page_read_bytes, 0, page_zero_bytes);

	return true;
}

/* Swap out the page by writeback contents to the file. */
static bool
file_backed_swap_out (struct page *page) {
	struct file_page *file_page UNUSED = &page->file;

	if (page == NULL)
		return false;

	struct container *aux = (struct container *)page->uninit.aux;

	// 사용 되었던 페이지(dirty page)인지 체크
	if (pml4_is_dirty(thread_current()->pml4, page->va))
	{
		file_write_at(aux->file, page->va, aux->page_read_bytes, aux->offset);
		pml4_set_dirty(thread_current()->pml4, page->va, 0);
	}

	pml4_clear_page(thread_current()->pml4, page->va);
}

swap out에서 dirty 확인시 파일이 업데이트 된 경우 백업파일에 내용을 수정후 페이지를 교체한 후 다시 dirty비트를 초기화 해주는 과정이 필요하다.

'OS > Pintos P.J_3' 카테고리의 다른 글

Pintos project3_Memory Mapped Files  (0) 2022.01.22
Pintos project3_Stack Growth  (0) 2022.01.21
Pintos project3_Anonymous Page  (0) 2022.01.21
Pintos project3_Memory management  (0) 2022.01.19
[Project 3_Virtual Memory]_Intro  (0) 2022.01.11