PintOS_Project03_Swap In/Out

전두엽힘주기·2025년 6월 6일

PintOS

목록 보기
19/20

메모리 스와핑 (Memory Swapping)

개요

  • 메모리 스와핑은 물리 메모리의 활용을 극대화하기 위한 메모리 회수 기법이다.
  • 메인 메모리의 프레임이 모두 할당된 상태에서 새로운 메모리 할당 요청이 들어오면, 운영체제는 사용되지 않는 페이지를 디스크로 스왑 아웃하여 공간을 확보한다.
  • 나중에 그 페이지가 필요해지면 디스크에서 다시 메모리로 스왑 인한다.

스와핑 기본 원리

  • Swap Out: 사용되지 않는 페이지를 디스크에 저장
  • Swap In: 디스크에 저장된 페이지를 다시 메모리로 복원
  • 운영체제가 스와핑을 관리하며, 함수 포인터(struct page_operations)를 통해 호출된다.
  • Evict 대상 페이지는:
    • 익명 페이지 (anonymous page)
    • 파일 기반 페이지 (file-backed page)

익명 페이지 (Anonymous Page)

익명 페이지 특징

  • 파일과 연결되지 않은 메모리 전용 페이지
  • 스왑 디스크를 임시 백업 저장소로 사용
  • 스왑 단위는 PGSIZE = 4096 bytes

함수 구현

void vm_anon_init(void)

  • 스왑 디스크 설정

  • 스왑 테이블 (예: 비트맵) 생성

  • 페이지 단위로 스왑 슬롯 관리

    Pintos uses disks this way: 1:1 - swap
    (주석으로 나와있다)

static struct bitmap *swap_table;   // 스왑 슬롯 사용 여부 관리용 비트맵
void vm_anon_init(void) {
    swap_disk = disk_get(1, 1);  // 채널 1, 장치 1 = 스왑 디스크
    ASSERT(swap_disk != NULL);

    size_t sector_cnt = disk_size(swap_disk);  // 전체 섹터 수
    size_t slots = sector_cnt / (PGSIZE / DISK_SECTOR_SIZE);  // 한 페이지 = 8 섹터

    swap_table = bitmap_create(slots);
    ASSERT(swap_table != NULL);
}

bool anon_initializer(struct page *page, enum vm_type type, void *kva)

  • anon_page에 스왑 슬롯 인덱스를 저장할 수 있는 필드 추가 필요
struct anon_page {
    size_t swap_slot;
};
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;

	/* Initialize the swap slot to invalid */ //초기화
	anon_page->swap_slot = BITMAP_ERROR; 

	return true;
}

스왑 함수

static bool anon_swap_out(struct page *page)

  • 빈 스왑 슬롯 검색
  • 페이지 내용을 디스크로 복사
  • 슬롯 인덱스를 page에 저장
  • 스왑 공간 부족 시 커널 패닉
static bool
anon_swap_out (struct page *page) {
	struct anon_page *anon_page = &page->anon;

	size_t slot=bitmap_scan_and_flip(swap_table,0,1,false); //	swap_table에서 false인 비트를 하나 찾아서 true로 바꿔주고, 그 비트의 인덱스 (slot 번호) 를 반환
	if (slot == BITMAP_ERROR){
		PANIC("Swap disk is full!");
	}

	// 2. 페이지 내용을 스왑 디스크에 저장
	uint8_t *kva = page->va;  // 페이지의 커널 가상 주소
	for (int i = 0; i < SECTORS_PER_PAGE; i++) {
		disk_write(swap_disk, slot * SECTORS_PER_PAGE + i, kva + i * DISK_SECTOR_SIZE); //스왑 디스크(swap_disk)의 slot번째 슬롯의 i번째 섹터에, 현재 페이지(kva)의 i번째 512바이트 데이터를 기록
	}

	// 3. 슬롯 인덱스를 페이지에 저장
	anon_page->swap_slot = slot;

	// 4. 페이지와 프레임의 연결 끊기
	page->frame->page = NULL;
	page->frame = NULL;

	return true;
	
}

static bool anon_swap_in(struct page *page, void *kva)

  • page에 저장된 슬롯 인덱스를 통해 디스크에서 데이터 복사
  • 스왑 슬롯을 free 처리

static void anon_destroy (struct page *page)

static void
anon_destroy (struct page *page) {
	struct anon_page *anon_page = &page->anon;

		// 스왑 슬롯이 유효하다면 반환
	if (anon_page->swap_slot != BITMAP_ERROR) {
		bitmap_reset(swap_table, anon_page->swap_slot);
		anon_page->swap_slot = BITMAP_ERROR;  // 안전하게 초기화
	}
}

파일 기반 페이지 (File-Backed Page)

파일 페이지 특징

  • 파일 시스템에 매핑된 페이지
  • 스왑 디스크 대신 파일 자체를 백업 저장소로 사용
  • mmap에 의해 매핑된 파일로부터 읽기/쓰기

함수 구현

static bool file_backed_swap_out(struct page *page)

  • pml4_is_dirty()로 dirty 확인
  • dirty면 파일에 write
  • 이후 dirty 비트 clear

static bool file_backed_swap_in(struct page *page, void *kva)

  • 파일에서 데이터를 읽어와 메모리 복원
  • 파일 시스템 동기화 필요 (락 등 고려)

구현 파일

  • vm/anon.c: 익명 페이지 관련 함수들 구현
  • vm/file.c: 파일 기반 페이지 관련 함수들 구현
    • file_backed_init
    • file_initializer
    • file_backed_swap_in
    • file_backed_swap_out

0개의 댓글