๋ง๊ฐ๋กœ๊ทธ

ํฌ๋ž˜ํ”„ํ†ค ์ •๊ธ€ WEEK10 DAY 80 - PintOS Project3 VM (Memory Management ) ๋ณธ๋ฌธ

Krafton jungle

ํฌ๋ž˜ํ”„ํ†ค ์ •๊ธ€ WEEK10 DAY 80 - PintOS Project3 VM (Memory Management )

habbn 2024. 3. 27. 21:26
728x90
๐Ÿ“†2024.03.27

1. PintOS Project3 VM (Memory Management)

 

Implement Supplemental Page Table

: ๊ฐ ํŽ˜์ด์ง€์— ๋Œ€ํ•œ ์ถ”๊ฐ€์ ์ธ ์ •๋ณด๋ฅผ ๋‹ด๊ณ  ์žˆ์„ ๋ณด์ถฉ ํŽ˜์ด์ง€ ํ…Œ์ด๋ธ”์„ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.

/* ์ƒˆ ๋ณด์กฐ ํŽ˜์ด์ง€ ํ…Œ์ด๋ธ”์„ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค. */
void
supplemental_page_table_init (struct supplemental_page_table *spt UNUSED) {
	hash_init(&spt->hash_table, page_hash, page_less, NULL);
}

 

struct page *
spt_find_page (struct supplemental_page_table *spt UNUSED, void *va UNUSED) {
	struct page *page = NULL;
	struct hash_elem *e;

	/* ํ• ์ผ: ์ด ํ•จ์ˆ˜๋ฅผ ์ฑ„์›Œ์ฃผ์„ธ์š”. */
	page->va = pg_round_down(va);
	e = hash_find(&spt->hash_table, &page->hash_elem);
	
	if(e != NULL)
		return hash_entry(e, struct page, hash_elem);
	else
		return NULL;
}	

/* Insert PAGE into spt with validation. */
/* ํŽ˜์ด์ง€๋ฅผ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ๊ฑฐ์ณ spt์— ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค. */
bool
spt_insert_page (struct supplemental_page_table *spt UNUSED, struct page *page UNUSED) {
	int succ = false;

	/* ํ• ์ผ: ์ด ํ•จ์ˆ˜๋ฅผ ์ฑ„์›Œ์ฃผ์„ธ์š”. */
	if(is_user_vaddr(page->va)){
		if(spt_find_page(spt, page->va) == NULL){
			hash_insert(&spt->hash_table, &page->hash_elem);
			succ = true;
		}
	}
	return succ;
}

 

Frame Management

 

static struct frame *
vm_get_frame (void) {
	struct frame *frame = malloc(sizeof(struct frame));
	if(frame == NULL){
		PANIC("todo");
	}
	/* ํ• ์ผ: ์ด ํ•จ์ˆ˜๋ฅผ ์ฑ„์›Œ์ฃผ์„ธ์š”. */
	frame->kva = palloc_get_page(PAL_USER | PAL_ZERO);

	if(frame->kva == NULL){
		free(frame);
		return vm_evict_frame();
	}	

	frame->page = NULL;

	ASSERT (frame != NULL);
	ASSERT (frame->page == NULL);

	return frame;
}
bool
vm_claim_page (void *va UNUSED) {
	struct page *page = NULL;
	/* ํ• ์ผ: ์ด ํ•จ์ˆ˜๋ฅผ ์ฑ„์›Œ์ฃผ์„ธ์š”. */
	page = spt_find_page(&thread_current()->spt, va);

	if(page == NULL)
		return false;
	return vm_do_claim_page(page);
}

/* Claim the PAGE and set up the mmu. */
/* ํŽ˜์ด์ง€๋ฅผ ์ฒญ๊ตฌํ•˜๊ณ  mmu๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. */
static bool
vm_do_claim_page (struct page *page) {
	struct frame *frame = vm_get_frame ();

	/* Set links */
	/* ๋งํฌ ์„ค์ • */
	frame->page = page;
	page->frame = frame;

	/* TODO: Insert page table entry to map page's VA to frame's PA. */
	/* ํ•  ์ผ: ํŽ˜์ด์ง€ ํ…Œ์ด๋ธ” ํ•ญ๋ชฉ์„ ์‚ฝ์ž…ํ•˜์—ฌ ํŽ˜์ด์ง€์˜ VA๋ฅผ ํ”„๋ ˆ์ž„์˜ PA์— ๋งคํ•‘ํ•ฉ๋‹ˆ๋‹ค. */
	if(pml4_get_page(thread_current()->pml4, page->va) == NULL){
		if (!pml4_set_page (thread_current ()->pml4, page->va, frame->kva, true)) {
			vm_dealloc_page (page);
			return false;
		}	
	}
	return swap_in (page, frame->kva);
}

 

 

 

์ถ”๊ฐ€์ ์œผ๋กœ ๊ตฌํ˜„ํ•˜๋ฉด์„œ ์—๋Ÿฌ๋‚ฌ๋˜ ๋ถ€๋ถ„์— ๋Œ€ํ•ด ์ •๋ฆฌํ•ด๋ดค๋‹ค.

 

์šฐ์„  hash_init() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์ธ์ž๋กœ ์ค„ hash_hash_func์™€ hash_less_func ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ–ˆ๋‹ค.

 

๊ทธ๋ž˜์„œ ์ด์™€ ๊ฐ™์ด ํ•จ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•ด์คฌ๋Š”๋ฐ ์ž๊พธ ์žฌ์„ ์–ธ๋˜์—ˆ๋‹ค๋Š” ์—๋Ÿฌ๊ฐ€ ๋–ด์—ˆ๋‹ค.

uint64_t hash_hash_func (const struct hash_elem *e, void *aux)
{
	const struct page *p = hash_entry(e, struct page, hash_elem);
	return hash_bytes(&p->va, sizeof p->addr);
}

bool hash_less_func (const struct hash_elem *a, const struct hash_elem *b, void *aux)
{
	const struct page *pa = hash_entry(a, struct page, hash_elem);
	const struct page *pb = hash_entry(b, struct page, hash_elem);

	return pa->va < pb->va;
}

 

 

ํ•˜๋‚˜ํ•˜๋‚˜ ์ฐจ๊ทผ์ฐจ๊ทผํ•ด๋ณด๋‹ˆ ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•ด์ค€ ๊ฒƒ์ด ์•„๋‹Œ hash_hash_func์™€ hash_less_func๋ผ๋Š” ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋ฅผ ๊ฐ€์ ธ๋‹ค ์žฌ์ •์˜๋ฅผ ํ•ด์ฃผ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒƒ์ด์—ˆ๋‹ค.

์•„์ฐจ์ฐจ..!

uint64_t page_hash (const struct hash_elem *e, void *aux)
{
	const struct page *p = hash_entry(e, struct page, hash_elem);
	return hash_bytes(&p->va, sizeof p->va);
}


bool page_less (const struct hash_elem *a, const struct hash_elem *b, void *aux)
{
	const struct page *pa = hash_entry(a, struct page, hash_elem);
	const struct page *pb = hash_entry(b, struct page, hash_elem);

	return pa->va < pb->va;
}

 

๊นƒ๋ถ์—์„œ๋„ page_hash์™€ page_less ๋ผ๊ณ  ์ ํ˜€์žˆ์—ˆ์ง€๋งŒ ๋‚˜์˜ ๊ฐ„๊ณผํ•œ ์‹ค์ˆ˜์˜€๋‹ค..

 

page_hash() ํ•จ์ˆ˜์˜ ์—ญํ•  ?

ํ•ด์‹œํ…Œ์ด๋ธ”์—์„œ๋Š” ํŠน์ • ํ‚ค๋ฅผ ํ•ด์‹œ๊ฐ’์œผ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ํ•ด๋‹น ํ•ด์‹œ๊ฐ’์— ๋Œ€์‘ํ•˜๋Š” ๋ฒ„ํ‚ท์— ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•œ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด ํ‚ค์˜ ํ•ด์‹œ๊ฐ’์„ ๊ณ„์‚ฐํ•˜๋Š” ํ•จ์ˆ˜๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

hash_byte ํ•จ์ˆ˜๋Š” ์ฃผ์–ด์ง„ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ํ•ด์‹œ๊ฐ’์„ ๊ณ„์‚ฐํ•œ๋‹ค. ์ฃผ์†Œ์™€ ํฌ๊ธฐ๋ฅผ ์ธ์ž๋กœ ๋ฐ›์•„ ํŽ˜์ด์ง€ ์ฃผ์†Œ๋ฅผ ํ•ด์‹œ๊ฐ’์œผ๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.

 

page_less() ํ•จ์ˆ˜์˜ ์—ญํ•  ?

๋น„๊ตํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด์‹œ ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•˜๋ฉด, ํŠน์ • ๊ฐ€์ƒ ์ฃผ์†Œ์— ๋Œ€ํ•œ ํŽ˜์ด์ง€๋ฅผ ํ•ด์‹œ ํ…Œ์ด๋ธ”์— ์‚ฝ์ž…ํ•˜๊ฑฐ๋‚˜ ๊ฒ€์ƒ‰ํ•  ๋•Œ ํŽ˜์ด์ง€์˜ ๊ฐ€์ƒ ์ฃผ์†Œ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํŽ˜์ด์ง€๋ฅผ ์ •๋ ฌํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

typedef uint64_t hash_hash_func (const struct hash_elem *e, void *aux);

typedef bool hash_less_func (const struct hash_elem *a, const struct hash_elem *b, void *aux);

 

hash_hash_func ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋Š” ํ•ด์‹œ ํ…Œ์ด๋ธ”์—์„œ ์š”์†Œ๋ฅผ ํ•ด์‹ฑํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋  ํ•จ์ˆ˜๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ณ ,

hash_less_func ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋Š” ํ•ด์‹œ ํ…Œ์ด๋ธ”์—์„œ ์š”์†Œ๋ฅผ ๋น„๊ตํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋œ๋‹ค. 

์ด๋Ÿฌํ•œ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ ํƒ€์ž…์„ ์ •์˜ํ•จ์œผ๋กœ์จ, ์ž์‹ ๋งŒ์˜ ํ•ด์‹œ ํ•จ์ˆ˜์™€ ๋น„๊ต ํ•จ์ˆ˜๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ ํ•ด์‹œ ํ…Œ์ด๋ธ”์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์•ผ ํ•œ๋‹ค.

 

 

 

728x90