2023. 5. 19. 11:27ใComputer Science
๐ก ์ด๋ฒ ํํธ์์๋ Anonymous page๋ผ๊ณ ๋ถ๋ฆฌ๋ non-disk based image๋ฅผ ๊ตฌํํ๋ค.
Anonymous Page๋?
ํ์ผ์ ๊ธฐ๋ฐ์ผ๋ก ํ๋ file-backed page์ ๋ฌ๋ฆฌ, ์ด๋ฆ์ด ์ง์ ๋ ํ์ผ ์์ค๊ฐ ์๊ธฐ ๋๋ฌธ์ anonymous๋ผ๊ณ ๋ถ๋ฆฌ๋ฉฐ,
์คํ๊ณผ ํ ์์ญ์์ ์ฌ์ฉ๋๋ค.
Lazy Loading์ ์ด์ฉํ ํ์ด์ง ์ด๊ธฐํ
- Lazy loading์ ๋ฉ๋ชจ๋ฆฌ ๋ก๋ฉ์ ํ์ํ ์์ ๊น์ง ๋ฏธ๋ฃจ๋ ๋์์ธ ํจํด์ด๋ค.
- Lazy Loading์ ๊ตฌํํ๊ธฐ ์ํด์๋ ํ์ด์ง๋ฅผ ํ ๋นํ ๋ ํด๋น ํ์ด์ง์ ๋์ํ๋ page ๊ตฌ์กฐ์ฒด๋ง ๋ง๋ค๊ณ , ๋ฌผ๋ฆฌ frame ํ ๋น โ ์ค์ ๋ด์ฉ๋ โ (์์ง์ ๋ก๋ฉํ์ง ์๋๋ค!)
- ๊ทธ๋ผ ๋ด์ฉ์ ์ธ์ ๋ก๋ํ์ง ?! ๐๐ป ์ค์ ๋ก ๋ด์ฉ์ด ๋ก๋๋๋ ์์ ์ page fault๊ฐ ๋ฐ์ํ๋ ์์ ์ด๋ค.
page fault๊ฐ ๋ฐ์ํ๋ค๋ ๊ฒ์ ์ด ์ฃผ์์ ์ ๊ทผํ๋ค๋ ๊ฒ์ด๊ณ , ์ ๊ทผํ๋ค๋ ๊ฒ์ ์ค์ ๋ก ๋ด์ฉ์ด ํ์ํ ์์ ์ด ๋์๋ค๋ ๊ฒ์ ์๋ฏธํ๋ค.
์ด page fault ์๊ทธ๋์ ๋ฐ์์ ๋ ๋ด์ฉ์ด ๋ก๋๋๊ฒ ๊ตฌํํ๋ฉด Lazy Loading ์์ฑ~!
๐ค ์ด๊ฑฐ ์ ํ์ง?
๋ฉ๋ชจ๋ฆฌ ํจ์จ์ฑ์ ์ํด์!
Lazy loading์ ์ฌ์ฉํ๋ฉด ํ๋ก์ธ์ค๊ฐ ํ์ํ ํ์ด์ง๋ฅผ ํ์ํ ์์ ์ ๋ก๋ํ ์ ์๊ณ , ์ด๋ ๊ฒ ํจ์ผ๋ก์จ ๋ถํ์ํ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ์ ์ค์ผ ์ ์๋ค.
Page initialization flow
ํ์ด์ง๊ฐ ์ด๊ธฐํ๋๋ ๊ณผ์ ์ ๋จผ์ ์ดํด๋ณด์.
- uninit ํ์ด์ง ๊ตฌ์กฐ์ฒด ์์ฑ : ์ปค๋์ด ์๋ก์ด ํ์ด์ง ์์ฒญ์ ๋ฐ์ผ๋ฉด vm_alloc_page_with_initializer ํจ์๊ฐ ํธ์ถ๋๋ค.
- ์ด ํจ์๋ ํ์ด์ง ๊ตฌ์กฐ์ฒด๋ฅผ ์์ฑํ๊ณ , ์ด ๊ตฌ์กฐ์ฒด์ ํ์ด์ง ์ ํ์ ๋ง๋ ์ ์ ํ ์ด๊ธฐํ ํจ์๋ค์ ๋ด์๋๋ค.
(์ด๊ธฐํ๋ฅผ ํ์ง๋ ์๊ณ ์ด๊ธฐํํ ๋ ์ด๋ค ํจ์๋ฅผ ์ฌ์ฉํด์ผ ํ๋์ง ๋ด์๋ง! ๋๋ค.)
์ด๋ ๊ฒ ์ด๊ธฐํ๋์ง ์์ ์ํ์ ํ์ด์ง์ ํ์ ์ VM๊ณผ uninitialized์ ์ฝ์๋ฅผ ํฉ์น VM_UNINIT์ด๋ค.
- ์ด ํจ์๋ ํ์ด์ง ๊ตฌ์กฐ์ฒด๋ฅผ ์์ฑํ๊ณ , ์ด ๊ตฌ์กฐ์ฒด์ ํ์ด์ง ์ ํ์ ๋ง๋ ์ ์ ํ ์ด๊ธฐํ ํจ์๋ค์ ๋ด์๋๋ค.
- lazy loading์ ๊ตฌํํ๊ฒ ๋๋ฉด, ์์์ ์ธ๊ธํ ๋ฐ์ ๊ฐ์ด user ํ๋ก๊ทธ๋จ์ด ์ ํ์ด์ง์ ์ฒ์ ์ ๊ทผํ์ ๋ page fault๊ฐ ๋ฐ์ํ๊ฒ ๋๋๋ฐ, ๊ทธ ์ด์ ๋, ๋ด์ฉ์ด ์์ ๋ฟ๋๋ฌ ํ ๋น๋ ๋ฌผ๋ฆฌ ํ๋ ์๋ ์๊ธฐ ๋๋ฌธ์ด๋ค!
- page fault๊ฐ ๋ฐ์ํ์ ๋ ์ ๊ทผํ ๋ฉ๋ชจ๋ฆฌ์ physical frame์ด ์กด์ฌํ์ง ์๋ค๋ ๊ฒ์ด ํ์ธ๋๋ค๋ฉด ์ด๋๊ฐ ๋ฐ๋ก loading์ด ํ์ํ ์์ ์ด๋ค!
์ด๋ ๋ฌผ๋ฆฌ ํ๋ ์์ ํ ๋นํ๊ณ ๋์ uninit_initialize๊ฐ ํธ์ถ๋๋ฉด์ ์์ ์ค์ ํ ์ด๊ธฐํ ํจ์๋ค์ด ํธ์ถ๋์ด ๋๋์ด ์ด๊ธฐํ๊ฐ ์ด๋ฃจ์ด์ง๋ค.- ์ด๊ธฐํ ํจ์๋ ์ต๋ช ํ์ด์ง์ ๊ฒฝ์ฐ anon_initializer, ํ์ผ ๊ธฐ๋ฐ ํ์ด์ง์ ๊ฒฝ์ฐ file_backed_initializer์ด๋ค.
- ํ์ด์ง ๋ณ ์ด๊ธฐํ ํจ์ ์ธ์๋ lazy_load_segment ํจ์๊ฐ ํธ์ถ๋๋ฉฐ ์ด ํจ์์์ ๋ด์ฉ์ด ๋ก๋๋๋ค.
Lazy Loading for Executable
๐ก Implement
vm_alloc_page_with_initializer()
.
1) vm_alloc_page_with_initializer
๐ฅ ๋ชฉํ: page ๊ตฌ์กฐ์ฒด๋ฅผ ์์ฑํ๊ณ ์ ์ ํ ์ด๊ธฐํ ํจ์๋ฅผ ์ค์ ํ๋ค.
page ๊ตฌ์กฐ์ฒด ์์ฑ
- page ๊ตฌ์กฐ์ฒด๋ฅผ ํ๋ ํ ๋น๋ฐ๋๋ค.
uninit ํ์ ์ผ๋ก ์ด๊ธฐํ & ์ด๊ธฐํ ํจ์ ์ค์
- uninit_new ํจ์์ ์ญํ ์ ์ฌ๊ธฐ์๋ uninit ํ์ ์ผ๋ก ์ด๊ธฐํ์ํจ๋ค๊ณ ๋ง ์์๋๊ณ , ์๋์์ ์์ธํ ์์๋ณผ ๊ฒ์ด๋ค!
- ์ด page๋ฅผ uninit ํ์
์ผ๋ก ์ด๊ธฐํํ๊ธฐ ์ํด์ uninit_new ํจ์๋ฅผ ํธ์ถํด์ผ ํ๋๋ฐ,
uninit_new ํจ์๋ฅผ ํธ์ถํ ๋ ํ์ํ ์ธ์๋ ์๋์ ๊ฐ๋ค.p
์ด๊ธฐํํ page ๊ตฌ์กฐ์ฒดupage
p๋ฅผ ํ ๋นํ ๊ฐ์ ์ฃผ์init
p์ ๋ด์ฉ์ ์ด๊ธฐํํ๋ ํจ์aux
init์ ํ์ํ ๋ณด์กฐ๊ฐinitializer
p๋ฅผ ํ์ ์ ๋ง๊ฒ ์ด๊ธฐํํ๋ ํจ์
- ์ธ์ ์ค์์
p
๋ ์์์ ํ ๋น๋ฐ์ page ๊ตฌ์กฐ์ฒด๋ฅผ ๋ฃ์ด์ฃผ๋ฉด ๋๊ณ ,upage
,init
,aux
๋ ์ผ๋จ vm_alloc_page_with_initializer๊ฐ ์ ๋ฌ ๋ฐ์ ๋งค๊ฐ๋ณ์๋ค์ ๊ทธ๋๋ก ์ ๋ฌํ๋ฉด ๋๋ค. (์๋์์ ์ค๋ช ) - ๋ง์ง๋ง ์ธ์์ธ
initializer
๋ ๋งค๊ฐ๋ณ์๋ก ๋ค์ด์จ type์ ๋ฐ๋ผ ๋ถ๊ธฐ๊ฐ ํ์ํ๋ฐ,
1) anon ํ์ ์ด๋ฉด anon_initializer๋ฅผ, 2) file_backed ํ์ ์ด๋ฉด file_backed_initializer๋ฅผ ํจ์ ํฌ์ธํฐ๋ก ์ ๋ฌํด์ผ ํ๋ค.- ์ค์ ๋ก C ์ธ์ด์๋ "ํด๋์ค"๋ "์์"์ด ์์ง๋ง, ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์ "ํด๋์ค ์์" ๊ฐ๋ ์ ๋์ ํ๊ธฐ ์ํด ํจ์ ํฌ์ธํฐ๋ฅผ ์ฌ์ฉํ๋ค.
- ํจ์ ํฌ์ธํฐ๋ฅผ ์ ๋ฌํ๋ค๋ ๊ฒ์ด ์์ํ๊ฒ ๋๊ปด์ง๋๋ฐ,
uninit_new ํจ์์ ์ ์ธ๋์ด ์๋ ํจ์ ํฌ์ธํฐ์ ํ์ ์ธbool (*initializer)(struct page *, enum vm_type, void *)
์ ๋ฆฌํด ํ์ ๊ณผ ๋งค๊ฐ๋ณ์์ ํ์ ์ด ์ผ์นํ๋ ํจ์๋ฅผ ์ ๋ฌํ๋ฉด ๋๋ค. - initializer๋ผ๋ ์ด๋ฆ์ ๋งค๊ฐ๋ณ์์ ์ด๋ฆ์ ๋ถ๊ณผํ๋ฏ๋ก ์ด๋ฆ์ ๋ฌ๋ผ์ ธ๋ ์๊ด ์๋ค.
- ํจ์ ์์ฒด๊ฐ ์ฃผ์๊ฐ์ ์ง๋๊ธฐ ๋๋ฌธ์ & ๊ธฐํธ ์์ด ํจ์๋ช ๋ง ์ ๋ฌํ๋ฉด ๋๋ค.
- ์ ํ์ ์ผ๋ก ์ ์ธํด๋๊ณ ๋ณ์์ฒ๋ผ ๊ฐ์ ๋ฐ๊พธ๋ ๋ฐฉ์์ผ๋ก ๊ตฌํํ๋ค.
page ๊ตฌ์กฐ์ฒด์ ํ๋ ์์
- ๋งค๊ฐ๋ณ์ writable์ page ๊ตฌ์กฐ์ฒด์ writable ํ๋์ ํ ๋นํ๋ค.
- (์ด๋ฅผ ์ํด ๋จผ์ page ๊ตฌ์กฐ์ฒด์ writable ํ๋๋ฅผ ์ถ๊ฐํด์ผ ํ๋ค.)
- ํ๋์ ๊ฐ์ ์์ ํ ๋๋ uninit_new ํจ์๊ฐ ํธ์ถ๋ ์ดํ์ ์์ ํด์ผ ํ๋ค.
Why? uninit_new ํจ์ ์์์ ๊ตฌ์กฐ์ฒด ๋ด์ฉ์ด ์ ๋ถ ์๋ก ํ ๋น๋๊ธฐ ๋๋ฌธ์ด๋ค. uninit_new ํจ์ ํธ์ถ ์ด์ ์๋ ์๋ฌด๋ฆฌ ๊ฐ์ ์ถ๊ฐํด๋ ๋ค ๋ ๋ผ๊ฐ๋ ์์์ ์ ์ํด์ผ ํ๋ค!!!
page๋ฅผ SPT์ ์ฝ์
- page๋ฅผ ์๋ก ๋ง๋ค์์ผ๋ page table์ ์ถ๊ฐํด์ผ๊ฒ ์ง! ์ด๊ธฐํ๊ฐ ์๋ฃ๋ page๋ฅผ ํ๋ก์ธ์ค์ SPT์ ์ฝ์ ํ๋ฉด ๋!
ํจ์ ๊ตฌํ์ ๋ง์ณค์ผ๋, ์ด์ ๋ถํฐ๋ ํ์ด์ง๋ฅผ ์์ฑํ ๋ ์ด ํจ์๋ฅผ ์ฌ์ฉํด์ ์์ฑํ๋ฉด ๋๋ค.
(Lazy Loading์ด ํ์ ์๋ ํ์ด์ง๋ฅผ ์์ฑํ ๋๋ vm_alloc_page์ ์ฌ์ฉํด๋ ๋๋ค.)
bool vm_alloc_page_with_initializer(enum vm_type type, void *upage, bool writable,
vm_initializer *init, void *aux)
{
ASSERT(VM_TYPE(type) != VM_UNINIT)
struct supplemental_page_table *spt = &thread_current()->spt;
/* Check wheter the upage is already occupied or not. */
// upage๊ฐ ์ด๋ฏธ ์ฌ์ฉ ์ค์ธ์ง ํ์ธํฉ๋๋ค.
if (spt_find_page(spt, upage) == NULL)
{
/* TODO: Create the page, fetch the initialier according to the VM type,
* TODO: and then create "uninit" page struct by calling uninit_new. You
* TODO: should modify the field after calling the uninit_new. */
// 1) ํ์ด์ง๋ฅผ ์์ฑํ๊ณ ,
struct page *p = (struct page *)malloc(sizeof(struct page));
// 2) type์ ๋ฐ๋ผ ์ด๊ธฐํ ํจ์๋ฅผ ๊ฐ์ ธ์์
bool (*page_initializer)(struct page *, enum vm_type, void *);
switch (VM_TYPE(type))
{
case VM_ANON:
page_initializer = anon_initializer;
break;
case VM_FILE:
page_initializer = file_backed_initializer;
break;
}
// 3) "uninit" ํ์
์ ํ์ด์ง๋ก ์ด๊ธฐํํ๋ค.
uninit_new(p, upage, init, type, aux, page_initializer);
// ํ๋ ์์ ์ uninit_new๋ฅผ ํธ์ถํ ์ดํ์ ํด์ผ ํ๋ค.
p->writable = writable;
// 4) ์์ฑํ ํ์ด์ง๋ฅผ SPT์ ์ถ๊ฐํ๋ค.
return spt_insert_page(spt, p);
}
err:
return false;
}
์์์ ์ฌ์ฉํ uninit_new ํจ์์ ํ๋ฆ์ ๋ฐ๋ผ๊ฐ๋ณด์!
uninit_new ํจ์๊ฐ ํ๋ ์ผ
- uninit_new ํจ์์์๋ ๋งค๊ฐ๋ณ์๋ก ๋ฐ์ page ๊ตฌ์กฐ์ฒด๋ฅผ uninit type์ผ๋ก ๋ง๋ ๋ค.
(page ๊ตฌ์กฐ์ฒด๋ uninit/anon/file/page_cache ์ค ํ๊ฐ์ง ํ์ ์ ๊ฐ์ง๋๋ฐ, ์ฌ๊ธฐ์๋ uninit ํ์ ์ผ๋ก ๋ง๋๋ ๊ฑฐ๋๊น page ๊ตฌ์กฐ์ฒด์ uninit ํ๋๊ฐ ์๊ธฐ๋ ๊ฒ์ด๋ค.) - page->operations์๋ uninit_ops๊ฐ ๋ด๊ธฐ๋๋ฐ ์ด ๊ตฌ์กฐ์ฒด๋ฅผ ๋ณด๋ฉด swap_in์
uninit_initialize
๊ฐ ๋ด๊ฒจ์๋ค.
ํ์ด์ง๊ฐ ์ค์ ๋ก ๋ก๋ฉ๋ ๋ ์ด swap_in(์ ๋ด๊ธด uninit_initialize)๊ฐ ํธ์ถ๋๊ฒ ๋๋ฉด์ (uninit ํ์ด์ง์) ์ด๊ธฐํ๊ฐ ์ด๋ฃจ์ด์ง๋ค.
(uninit_initialize ์์์ ์ง๊ธ ์ค์ ํ๋ ์ด๊ธฐํ ํจ์๋ค์ด ํธ์ถ๋๋ค.)
๐๐ป uninit_ops ๊ตฌ์กฐ์ฒด
- page->uninit->init์๋ ๋งค๊ฐ๋ณ์๋ก ๋ฐ์ init์ด ๋ด๊ธฐ๋๋ฐ ํจ์ ํธ์ถ์ ๊ฑฐ์ฌ๋ฌ ์ฌ๋ผ๊ฐ๋ณด๋ฉด process.c์ load_segment ํจ์์์ vm_alloc_page_with_initializer๋ฅผ ํธ์ถํ ๋ init ์ธ์๋ก lazy_load_segment๋ฅผ ์ ๋ฌํ ๊ฒ์ ์ ์ ์๋ค.
- page->uninit->page_initializer์๋ ๋งค๊ฐ๋ณ์๋ก ๋ฐ์ initializer๊ฐ ๋ด๊ธฐ๊ฒ ๋๋๋ฐ, ์ง๊ธ์ ANON ํ์ ์ ํ์ด์ง๋ฅผ ํ ๋นํ์ผ๋ฏ๋ก anon_initializer๊ฐ ๋ด๊ธธ ๊ฒ์ด๋ค.
- ํ์ด์ง๊ฐ ์ค์ ๋ก ๋ก๋ฉ๋ ๋(์ฒซ๋ฒ์งธ page fault๊ฐ ๋ฐ์ํ์ ๋) ํธ์ถ๋๋ swap_in์ page_fault์์ ์ด์ด์ง๋ vm_do_claim_page ํจ์์์ ํธ์ถ๋๊ณ ์๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
- swap_in์ ๋ด๊ฒจ์๋
uninit_initialize
์์๋ uninit->page_initializer์ uninit->init์ด ํธ์ถ๋๋๋ฐ, ์์์ ํ์ธํ ๋ฐ์ ๊ฐ์ด
uninit->page_initializer์๋anon_initializer
, uninit->init์๋lazy_load_segment
๊ฐ ๋ด๊ฒจ์์ด ์ด ๋ ํจ์๊ฐ ๊ฐ๊ฐ ํธ์ถ๋๋ค.
- ์ ๋ฆฌํด๋ณด๋ฉด, ์ฒซ๋ฒ์งธ page fault๊ฐ ๋ฐ์ํ๋ฉด์
vm_do_claim_page ํจ์์์ ๋งคํ์ด ์ด๋ฃจ์ด์ง ์ดํ์ (swap_in์ ํด๋นํ๋) uninit_initialize ํจ์๊ฐ ํธ์ถ๋๊ณ ,
๊ทธ ์์์ ๊ฐ ํ์ด์ง ํ์ ๋ณ ์ด๊ธฐํ ํจ์์ ๋ด์ฉ์ ๋ก๋ํ๋ ํจ์(lazy_load_segment)๊ฐ ํธ์ถ๋๋ ๊ฒ์ด๋ค.
์ด์ด์ ๋ด์ฉ์ ๋ก๋ํ๋ ํจ์์ธ load_segment์ lazy_load_segment๋ฅผ ์ดํด๋ณด์!
๐ก Implement
load_segment
andlazy_load_segment
inuserprog/process.c
.
2) load_segment
- ์ด ํจ์๋ ํ๋ก์ธ์ค๊ฐ ์คํ๋ ๋ ์คํ ํ์ผ์ ํ์ฌ ์ค๋ ๋๋ก ๋ก๋ํ๋ ํจ์์ธ load ํจ์์์ ํธ์ถ๋๋ค.
- ํ์ผ์ ๋ด์ฉ์ upage์ ๋ก๋ํ๋ ํจ์์ด๋ค.
ํ์ผ์ ๋ด์ฉ์ ๋ก๋ํ๊ธฐ ์ํด์ upage๋ฅผ ํ ๋นํ page๊ฐ ํ์ํ๋ฐ, ์์์ ์์ ํ vm_alloc_page_with_initializer ํจ์๋ฅผ ํธ์ถํด์ ํ์ด์ง๋ฅผ ์์ฑํ๋ค. - Lazy Loading์ ์ฌ์ฉํด์ผ ํ๋ฏ๋ก, ์ฌ๊ธฐ์ ๋ฐ๋ก ํ์ผ์ ๋ด์ฉ์ ๋ก๋ํ์ง ์์์ผ ํ๋ค.
๊ทธ๋์ page์ ๋ด์ฉ์ ๋ก๋ํ ๋ ์ฌ์ฉํ ํจ์์ ํ์ํ ์ธ์๋ค์ ๋ฃ์ด์ค์ผ ํ๋๋ฐ,
vm_alloc_page_with_initializer ํจ์์ ๋ค ๋ฒ์งธ, ๋ค์ฏ ๋ฒ์งธ ์ธ์๊ฐ ๊ฐ๊ฐ ๋ก๋ํ ๋ ์ฌ์ฉํ ํจ์, ๊ทธ๋ฆฌ๊ณ ๊ทธ๋ ํ์ํ ์ธ์์ ํด๋นํ๋ค. - ๋ด์ฉ์ ๋ก๋ํ ๋ ์ฌ์ฉํ ํจ์๋ lazy_load_segment๋ฅผ ์ฌ์ฉํ๊ณ , ์ธ์๋ ์ง์ ๋ง๋ค์ด์ ๋๊ฒจ์ฃผ์ด์ผ ํ๋ค.
lazy_load_segment์์ ํ์ํ(์ธ์๋ก ๋๊ฒจ์ค์ผ ํ ) ์ ๋ณด๋ ์๋์ ๊ฐ๋ค.- `file` ๋ด์ฉ์ด ๋ด๊ธด ํ์ผ ๊ฐ์ฒด
- `ofs` ์ด ํ์ด์ง์์ ์ฝ๊ธฐ ์์ํ ์์น
- `read_bytes` ์ด ํ์ด์ง์์ ์ฝ์ด์ผ ํ๋ ๋ฐ์ดํธ ์
- `zero_bytes` ์ด ํ์ด์ง์์ read_bytes๋งํผ ์ฝ๊ณ ๊ณต๊ฐ์ด ๋จ์ 0์ผ๋ก ์ฑ์์ผ ํ๋ ๋ฐ์ดํธ ์
- lazy_load_arg๋ผ๋ ๊ตฌ์กฐ์ฒด๋ฅผ ์๋ก ์ ์ํด์ ์ ์ธํ๊ณ ์์ ์ ์ ๋ณด๋ค์ ๋ด์์ vm_alloc_page_with_initializer ํจ์์ ๋ง์ง๋ง ์ธ์๋ก ์ ๋ฌํ๋ค.
- ์ด์ page fault๊ฐ ์ฒ์ ๋ฐ์ํ์ ๋, lazy_load_segment๊ฐ ์คํ๋๊ณ lazy_load_arg๊ฐ ์ธ์๋ก ์ฌ์ฉ๋์ด ๋ด์ฉ์ด ๋ก๋ฉ๋ ๊ฒ์ด๋ค.
static bool
load_segment(struct file *file, off_t ofs, uint8_t *upage,
uint32_t read_bytes, uint32_t zero_bytes, bool writable)
{
ASSERT((read_bytes + zero_bytes) % PGSIZE == 0); // read_bytes + zero_bytes๊ฐ ํ์ด์ง ํฌ๊ธฐ(PGSIZE)์ ๋ฐฐ์์ธ์ง ํ์ธ
ASSERT(pg_ofs(upage) == 0); // upage๊ฐ ํ์ด์ง ์ ๋ ฌ๋์ด ์๋์ง ํ์ธ
ASSERT(ofs % PGSIZE == 0) // ofs๊ฐ ํ์ด์ง ์ ๋ ฌ๋์ด ์๋์ง ํ์ธ;
while (read_bytes > 0 || zero_bytes > 0) // read_bytes์ zero_bytes๊ฐ 0๋ณด๋ค ํฐ ๋์ ๋ฃจํ๋ฅผ ์คํ
{
/* Do calculate how to fill this page.
* We will read PAGE_READ_BYTES bytes from FILE
* and zero the final PAGE_ZERO_BYTES bytes. */
// ์ด ํ์ด์ง๋ฅผ ์ฑ์ฐ๋ ๋ฐฉ๋ฒ์ ๊ณ์ฐํฉ๋๋ค. ํ์ผ์์ PAGE_READ_BYTES ๋งํผ ์ฝ๊ณ ๋๋จธ์ง PAGE_ZERO_BYTES ๋งํผ 0์ผ๋ก ์ฑ์๋๋ค.
size_t page_read_bytes = read_bytes < PGSIZE ? read_bytes : PGSIZE; // ์ต๋๋ก ์ฝ์ ์ ์๋ ํฌ๊ธฐ๋ PGSIZE
size_t page_zero_bytes = PGSIZE - page_read_bytes;
/* TODO: Set up aux to pass information to the lazy_load_segment. */
// vm_alloc_page_with_initializer์ ์ ๊ณตํ aux ์ธ์๋ก ํ์ํ ๋ณด์กฐ ๊ฐ๋ค์ ์ค์ ํด์ผ ํฉ๋๋ค.
// loading์ ์ํด ํ์ํ ์ ๋ณด๋ฅผ ํฌํจํ๋ ๊ตฌ์กฐ์ฒด๋ฅผ ๋ง๋ค์ด์ผ ํฉ๋๋ค.
struct lazy_load_arg *lazy_load_arg = (struct lazy_load_arg *)malloc(sizeof(struct lazy_load_arg));
lazy_load_arg->file = file; // ๋ด์ฉ์ด ๋ด๊ธด ํ์ผ ๊ฐ์ฒด
lazy_load_arg->ofs = ofs; // ์ด ํ์ด์ง์์ ์ฝ๊ธฐ ์์ํ ์์น
lazy_load_arg->read_bytes = page_read_bytes; // ์ด ํ์ด์ง์์ ์ฝ์ด์ผ ํ๋ ๋ฐ์ดํธ ์
lazy_load_arg->zero_bytes = page_zero_bytes; // ์ด ํ์ด์ง์์ read_bytes๋งํผ ์ฝ๊ณ ๊ณต๊ฐ์ด ๋จ์ 0์ผ๋ก ์ฑ์์ผ ํ๋ ๋ฐ์ดํธ ์
// vm_alloc_page_with_initializer๋ฅผ ํธ์ถํ์ฌ ๋๊ธฐ ์ค์ธ ๊ฐ์ฒด๋ฅผ ์์ฑํฉ๋๋ค.
if (!vm_alloc_page_with_initializer(VM_ANON, upage,
writable, lazy_load_segment, lazy_load_arg))
return false;
/* Advance. */
// ๋ค์ ๋ฐ๋ณต์ ์ํ์ฌ ์ฝ์ด๋ค์ธ ๋งํผ ๊ฐ์ ๊ฐฑ์ ํฉ๋๋ค.
read_bytes -= page_read_bytes;
zero_bytes -= page_zero_bytes;
upage += PGSIZE;
ofs += page_read_bytes;
}
return true;
}
3) lazy_load_segment
- ์ด ํจ์๋ ์คํ ํ์ผ์ ๋ด์ฉ์ ํ์ด์ง๋ก ๋ก๋ฉํ๋ ํจ์์ด๋ฉฐ ์ฒซ๋ฒ์งธ page fault๊ฐ ๋ฐ์ํ ๋ ํธ์ถ๋๋ค.
- ์ด ํจ์๊ฐ ํธ์ถ๋๊ธฐ ์ด์ ์ ๋ฌผ๋ฆฌ ํ๋ ์ ๋งคํ์ด ์งํ๋๋ฏ๋ก, ์ฌ๊ธฐ์๋ ๋ฌผ๋ฆฌ ํ๋ ์์ ๋ด์ฉ์ ๋ก๋ฉํ๋ ์์ ๋ง ํ๋ฉด ๋๋ค.
- ์ด ํจ์๋ ํ์ด์ง ๊ตฌ์กฐ์ฒด์ aux๋ฅผ ์ธ์๋ก ๋ฐ๋๋ค.
- aux๋ load_segment์์ ๋ก๋ฉ์ ์ํด ์ค์ ํด๋ ์ ๋ณด์ธ lazy_load_arg์ด๋ค.
- ์ด ์ ๋ณด๋ฅผ ์ฌ์ฉํ์ฌ ์ฝ์ด์ฌ ํ์ผ์ ์ฐพ์์ ๋ฉ๋ชจ๋ฆฌ์ ๋ก๋ฉํ๋ค.
bool lazy_load_segment(struct page *page, void *aux)
{
/* TODO: Load the segment from the file */
/* TODO: This called when the first page fault occurs on address VA. */
/* TODO: VA is available when calling this function. */
struct lazy_load_arg *lazy_load_arg = (struct lazy_load_arg *)aux;
// 1) ํ์ผ์ position์ ofs์ผ๋ก ์ง์ ํ๋ค.
file_seek(lazy_load_arg->file, lazy_load_arg->ofs);
// 2) ํ์ผ์ read_bytes๋งํผ ๋ฌผ๋ฆฌ ํ๋ ์์ ์ฝ์ด ๋ค์ธ๋ค.
if (file_read(lazy_load_arg->file, page->frame->kva, lazy_load_arg->read_bytes) != (int)(lazy_load_arg->read_bytes))
{
palloc_free_page(page->frame->kva);
return false;
}
// 3) ๋ค ์ฝ์ ์ง์ ๋ถํฐ zero_bytes๋งํผ 0์ผ๋ก ์ฑ์ด๋ค.
memset(page->frame->kva + lazy_load_arg->read_bytes, 0, lazy_load_arg->zero_bytes);
return true;
}
4) setup_stack
- ์ด ํจ์๋ ํ๋ก์ธ์ค๊ฐ ์คํ๋ ๋ load ํจ์ ์์์ ํธ์ถ๋๋ฉฐ, STACK์ ํ์ด์ง๋ฅผ ์์ฑํ๋ ํจ์์ด๋ค.
- ์คํ์ ์๋๋ก ์ฑ์ฅํ๋ฏ๋ก, ์คํ์ ์์์ ์ธ USER_STACK์์ PGSIZE๋งํผ ์๋๋ก ๋ด๋ฆฐ ์ง์ (stack_bottom)์์ ํ์ด์ง๋ฅผ ์์ฑํ๋ค.
- ์ฒซ ๋ฒ์งธ ์คํ ํ์ด์ง๋ Lazy Loading์ ํ ํ์๊ฐ ์๋ค. ํ๋ก์ธ์ค๊ฐ ์คํ๋ ๋ ์ด ํจ์๊ฐ ๋ถ๋ฆฌ๊ณ ๋์ command line arguments๋ฅผ ์คํ์ ์ถ๊ฐํ๊ธฐ ์ํด ์ด ์ฃผ์์ ๋ฐ๋ก ์ ๊ทผํ๊ธฐ ๋๋ฌธ์ด๋ค.
๋ฐ๋ผ์, ์ด ์ฃผ์์์ fault๊ฐ ๋ฐ์ํ ๋๊น์ง ๊ธฐ๋ค๋ฆด ํ์์์ด ๋ฐ๋ก ๋ฌผ๋ฆฌ ํ๋ ์์ ํ ๋น๋ฐ์ ๋๋๋ค. - ํ์ด์ง๋ฅผ ํ ๋น๋ฐ์ ๋ ์ด ํ์ด์ง๊ฐ ์คํ์ ํ์ด์ง์์ ํ์ํ๊ธฐ ์ํด์ ๋ณด์กฐ ๋ง์ปค๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
์ฌ์ฉ ๋ฐฉ๋ฒ์ ํ์ด์ง๋ฅผ ํ ๋น ๋ฐ์ ๋ ํ์ ๊ณผ ํจ๊ป VM_MARKER_0๋ฅผ ์ฌ์ฉํด์ ์คํ ํ์ด์ง๋ฅผ ํ์ํ๋ค. ๐๐ป ์คํ์์ ํ ๋น ๋ฐ๋ ํ์ด์ง์ ์ด ๋ง์ปค๋ก ํ์๋ฅผ ํด๋๋ฉด, ๋์ค์ ์ด ํ์ด์ง๊ฐ ์คํ์ ํ์ด์ง์ธ์ง ์๋์ง ๋ง์ปค๋ฅผ ํตํด์ ์ ์ ์์! - ๋ง์ง๋ง์ผ๋ก, rsp ๊ฐ์ USER_STACK์ผ๋ก ๋ณ๊ฒฝํด์ค๋ค. ์ด์ argument_stack ํจ์์์ ์ด ์์น(rsp)๋ถํฐ ์ธ์๋ฅผ pushํ๊ฒ ๋๋ค.
static bool
setup_stack(struct intr_frame *if_)
{
bool success = false;
// ์คํ์ ์๋๋ก ์ฑ์ฅํ๋ฏ๋ก, USER_STACK์์ PGSIZE๋งํผ ์๋๋ก ๋ด๋ฆฐ ์ง์ ์์ ํ์ด์ง๋ฅผ ์์ฑํ๋ค.
void *stack_bottom = (void *)(((uint8_t *)USER_STACK) - PGSIZE);
/* TODO: Map the stack on stack_bottom and claim the page immediately.
* TODO: If success, set the rsp accordingly.
* TODO: You should mark the page is stack. */
/* TODO: stack_bottom์ ์คํ์ ๋งคํํ๊ณ ํ์ด์ง๋ฅผ ์ฆ์ ์์ฒญํ์ธ์.
* TODO: ์ฑ๊ณตํ๋ฉด, rsp๋ฅผ ๊ทธ์ ๋ง๊ฒ ์ค์ ํ์ธ์.
* TODO: ํ์ด์ง๊ฐ ์คํ์์ ํ์ํด์ผ ํฉ๋๋ค. */
/* TODO: Your code goes here */
// 1) stack_bottom์ ํ์ด์ง๋ฅผ ํ๋ ํ ๋น๋ฐ๋๋ค.
if (vm_alloc_page(VM_ANON | VM_MARKER_0, stack_bottom, 1))
// VM_MARKER_0: ์คํ์ด ์ ์ฅ๋ ๋ฉ๋ชจ๋ฆฌ ํ์ด์ง์์ ์๋ณํ๊ธฐ ์ํด ์ถ๊ฐ
// writable: argument_stack()์์ ๊ฐ์ ๋ฃ์ด์ผ ํ๋ True
{
// 2) ํ ๋น ๋ฐ์ ํ์ด์ง์ ๋ฐ๋ก ๋ฌผ๋ฆฌ ํ๋ ์์ ๋งคํํ๋ค.
success = vm_claim_page(stack_bottom);
if (success)
// 3) rsp๋ฅผ ๋ณ๊ฒฝํ๋ค. (argument_stack์์ ์ด ์์น๋ถํฐ ์ธ์๋ฅผ pushํ๋ค.)
if_->rsp = USER_STACK;
}
return success;
}
5) vm_try_handle_fault
- ๋ง์ง๋ง์ผ๋ก, spt_find_page๋ฅผ ํตํด SPT๋ฅผ ์ฐธ์กฐํ์ฌ faulted address์ ํด๋นํ๋ ํ์ด์ง ๊ตฌ์กฐ์ฒด๋ฅผ ํด๊ฒฐํ๋๋ก vm_try_handle_fault ํจ์๋ฅผ ์์ ํด์ผ ํฉ๋๋ค.
- page_fault๊ฐ ๋ฐ์ํ๋ฉด ์ ์ด๊ถ์ ์ ๋ฌ ๋ฐ๋ ํจ์์ด๋ค.
- ์ด ํจ์์์ ํ ๋น๋ ๋ฌผ๋ฆฌ ํ๋ ์์ด ์กด์ฌํ์ง ์์์ ๋ฐ์ํ ์์ธ์ผ ๊ฒฝ์ฐ์๋ ๋งค๊ฐ๋ณ์์ธ not_present์ true๋ฅผ ์ ๋ฌ๋ฐ๋๋ค.
๊ทธ๋ด ๊ฒฝ์ฐ, SPT์์ ํด๋น ์ฃผ์์ ํด๋นํ๋ ํ์ด์ง๊ฐ ์๋์ง ํ์ธํด์ ์กด์ฌํ๋ค๋ฉด ํด๋น ํ์ด์ง์ ๋ฌผ๋ฆฌ ํ๋ ์ ํ ๋น์ ์์ฒญํ๋ vm_do_claim_page ํจ์๋ฅผ ํธ์ถํ๋ค.
์ด ํจ์์์๋ ์์์ ์ค์ ํ๋๋ก ๊ฐ ํ์ด์ง์ ๋ง๋ ์ด๊ธฐํ ํจ์๊ฐ ํธ์ถ๋๋ค. - not_present ๊ฐ์ด false์ธ ์ํฉ์ ์ดํด๋ณด๋ฉด,
๋ฌผ๋ฆฌ ํ๋ ์์ด ํ ๋น๋์ด ์์ง๋ง page fault๊ฐ ์ผ์ด๋ ๊ฒ์ด๋ฏ๋ก ๊ทธ ๊ฒฝ์ฐ๋ read-only page์ write๋ฅผ ํ ๊ฒฝ์ฐ๊ฐ ๋๋ค. ๋ฐ๋ผ์ not_present๊ฐ false์ธ ๊ฒฝ์ฐ๋ ์์ธ๋ก ์ฒ๋ฆฌํ๋ฉด ๋๋ค. (return false) - not_present๊ฐ true์ธ ๊ฒฝ์ฐ์๋, read-only page์ write ์์ฒญ์ ํ ๊ฒฝ์ฐ๊ฐ ์๊ธธ ์ ์์ผ๋ฏ๋ก ์ด์ ๋ํ ์์ธ ์ฒ๋ฆฌ๋ฅผ ์ถ๊ฐํ๋ค.
bool vm_try_handle_fault(struct intr_frame *f UNUSED, void *addr UNUSED,
bool user UNUSED, bool write UNUSED, bool not_present UNUSED)
{
struct supplemental_page_table *spt UNUSED = &thread_current()->spt;
struct page *page = NULL;
if (addr == NULL)
return false;
if (is_kernel_vaddr(addr))
return false;
if (not_present) // ์ ๊ทผํ ๋ฉ๋ชจ๋ฆฌ์ physical page๊ฐ ์กด์ฌํ์ง ์์ ๊ฒฝ์ฐ
{
/* TODO: Validate the fault */
page = spt_find_page(spt, addr);
if (page == NULL)
return false;
if (write == 1 && page->writable == 0) // write ๋ถ๊ฐ๋ฅํ ํ์ด์ง์ write ์์ฒญํ ๊ฒฝ์ฐ
return false;
return vm_do_claim_page(page);
}
return false;
}
๐ก ์ฌ๊ธฐ๊น์ง ๊ตฌํํ๋ฉด fork๋ฅผ ์ ์ธํ ํ๋ก์ ํธ 2์ ๋ชจ๋ ํ ์คํธ๊ฐ ํต๊ณผ๋๋ค!
- Test ๊ฒฐ๊ณผ (55 of 141 tests failed.)
pass tests/userprog/args-none
pass tests/userprog/args-single
pass tests/userprog/args-multiple
pass tests/userprog/args-many
pass tests/userprog/args-dbl-space
pass tests/userprog/halt
pass tests/userprog/exit
pass tests/userprog/create-normal
pass tests/userprog/create-empty
pass tests/userprog/create-null
pass tests/userprog/create-bad-ptr
pass tests/userprog/create-long
pass tests/userprog/create-exists
pass tests/userprog/create-bound
pass tests/userprog/open-normal
pass tests/userprog/open-missing
pass tests/userprog/open-boundary
pass tests/userprog/open-empty
pass tests/userprog/open-null
pass tests/userprog/open-bad-ptr
pass tests/userprog/open-twice
pass tests/userprog/close-normal
pass tests/userprog/close-twice
pass tests/userprog/close-bad-fd
pass tests/userprog/read-normal
pass tests/userprog/read-bad-ptr
pass tests/userprog/read-boundary
pass tests/userprog/read-zero
pass tests/userprog/read-stdout
pass tests/userprog/read-bad-fd
pass tests/userprog/write-normal
pass tests/userprog/write-bad-ptr
pass tests/userprog/write-boundary
pass tests/userprog/write-zero
pass tests/userprog/write-stdin
pass tests/userprog/write-bad-fd
FAIL tests/userprog/fork-once
FAIL tests/userprog/fork-multiple
FAIL tests/userprog/fork-recursive
FAIL tests/userprog/fork-read
FAIL tests/userprog/fork-close
FAIL tests/userprog/fork-boundary
pass tests/userprog/exec-once
pass tests/userprog/exec-arg
FAIL tests/userprog/exec-boundary
pass tests/userprog/exec-missing
pass tests/userprog/exec-bad-ptr
FAIL tests/userprog/exec-read
FAIL tests/userprog/wait-simple
FAIL tests/userprog/wait-twice
FAIL tests/userprog/wait-killed
pass tests/userprog/wait-bad-pid
FAIL tests/userprog/multi-recurse
FAIL tests/userprog/multi-child-fd
pass tests/userprog/rox-simple
FAIL tests/userprog/rox-child
FAIL tests/userprog/rox-multichild
pass tests/userprog/bad-read
pass tests/userprog/bad-write
pass tests/userprog/bad-read2
pass tests/userprog/bad-write2
pass tests/userprog/bad-jump
pass tests/userprog/bad-jump2
FAIL tests/vm/pt-grow-stack
pass tests/vm/pt-grow-bad
FAIL tests/vm/pt-big-stk-obj
pass tests/vm/pt-bad-addr
pass tests/vm/pt-bad-read
pass tests/vm/pt-write-code
FAIL tests/vm/pt-write-code2
FAIL tests/vm/pt-grow-stk-sc
pass tests/vm/page-linear
FAIL tests/vm/page-parallel
FAIL tests/vm/page-merge-seq
FAIL tests/vm/page-merge-par
FAIL tests/vm/page-merge-stk
FAIL tests/vm/page-merge-mm
pass tests/vm/page-shuffle
FAIL tests/vm/mmap-read
FAIL tests/vm/mmap-close
FAIL tests/vm/mmap-unmap
FAIL tests/vm/mmap-overlap
FAIL tests/vm/mmap-twice
FAIL tests/vm/mmap-write
pass tests/vm/mmap-ro
FAIL tests/vm/mmap-exit
FAIL tests/vm/mmap-shuffle
FAIL tests/vm/mmap-bad-fd
FAIL tests/vm/mmap-clean
FAIL tests/vm/mmap-inherit
FAIL tests/vm/mmap-misalign
FAIL tests/vm/mmap-null
FAIL tests/vm/mmap-over-code
FAIL tests/vm/mmap-over-data
FAIL tests/vm/mmap-over-stk
FAIL tests/vm/mmap-remove
pass tests/vm/mmap-zero
FAIL tests/vm/mmap-bad-fd2
FAIL tests/vm/mmap-bad-fd3
FAIL tests/vm/mmap-zero-len
FAIL tests/vm/mmap-off
FAIL tests/vm/mmap-bad-off
FAIL tests/vm/mmap-kernel
FAIL tests/vm/lazy-file
pass tests/vm/lazy-anon
FAIL tests/vm/swap-file
FAIL tests/vm/swap-anon
FAIL tests/vm/swap-iter
FAIL tests/vm/swap-fork
pass tests/filesys/base/lg-create
pass tests/filesys/base/lg-full
pass tests/filesys/base/lg-random
pass tests/filesys/base/lg-seq-block
pass tests/filesys/base/lg-seq-random
pass tests/filesys/base/sm-create
pass tests/filesys/base/sm-full
pass tests/filesys/base/sm-random
pass tests/filesys/base/sm-seq-block
pass tests/filesys/base/sm-seq-random
FAIL tests/filesys/base/syn-read
pass tests/filesys/base/syn-remove
FAIL tests/filesys/base/syn-write
pass tests/threads/alarm-single
pass tests/threads/alarm-multiple
pass tests/threads/alarm-simultaneous
pass tests/threads/alarm-priority
pass tests/threads/alarm-zero
pass tests/threads/alarm-negative
pass tests/threads/priority-change
pass tests/threads/priority-donate-one
pass tests/threads/priority-donate-multiple
pass tests/threads/priority-donate-multiple2
pass tests/threads/priority-donate-nest
pass tests/threads/priority-donate-sema
pass tests/threads/priority-donate-lower
pass tests/threads/priority-fifo
pass tests/threads/priority-preempt
pass tests/threads/priority-sema
pass tests/threads/priority-condvar
pass tests/threads/priority-donate-chain
FAIL tests/vm/cow/cow-simple
55 of 141 tests failed.
Project2์ fork ๊ด๋ จ ํ ์คํธ๊ฐ ์คํจํ๊ณ ์๋๋ฐ, ์ด๋ ์์ ํ๋ก์ธ์ค๋ฅผ ์์ฑํ ๋ ์ฌ์ฉ๋๋ ํจ์๋ฅผ ๊ตฌํํ์ง ์์๊ธฐ ๋๋ฌธ์ด๋ค.
์์ ํ๋ก์ธ์ค๋ฅผ ์์ฑํ ๋ ํธ์ถ๋๋ __do_fork ํจ์์์ supplemental_page_table_copy ํจ์๋ฅผ ํธ์ถํ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
์ด์ด์ ์ด ํจ์์ ๋ํด์ ์์๋ณด์!
Supplemental Page Table - Revisit
- ์์ ํ๋ก์ธ์ค๋ฅผ ์์ฑํ๊ฑฐ๋ ํ๋ก์ธ์ค๊ฐ ์ข ๋ฃ๋ ๋ ํ์ํ SPT๋ฅผ ๋ณต์ฌํ๋ ํจ์์ ์ ๋ฆฌํ๋ ํจ์ ๋ ๊ฐ์ง๊ฐ ์๋ค.
๐ก Implement
supplemental_page_table_copy
andsupplemental_page_table_kill
invm/vm.c
.
6) supplemental_page_table_copy
- ์์ ํ๋ก์ธ์ค๋ฅผ ์์ฑํ ๋ ๋ถ๋ชจ ํ๋ก์ธ์ค์ SPT๋ ์์์๊ฒ ์์ํด์ค์ผ ํ๋๋ฐ, ๊ทธ๋ ์ฌ์ฉ๋๋ ํจ์์ด๋ค.
- ๋ถ๋ชจ ํ๋ก์ธ์ค์ SPT์ ์๋ ๋ชจ๋ ํ์ด์ง๋ฅผ ๊ฐ ํ์ ์ ๋ง๊ฒ ํ ๋น์ ๋ฐ๊ณ , uninit ์ํ๊ฐ ์๋๋ผ๋ฉด, ์ฆ ๋ด์ฉ์ด ๋ก๋ฉ๋ ์ํ๋ผ๋ฉด ๋ฐ๋ก ๋งคํ์ ์งํํด์ ๋ด์ฉ๊น์ง ๊ทธ๋๋ก ๋ณต์ฌํ๋ค.
- file-backed page์ธ ๊ฒฝ์ฐ์๋ ๋ค๋ฅธ ์ฒ๋ฆฌ๊ฐ ํ์ํ์ง๋ง anonymous page ํํธ์์๋ ํ์ํ์ง ์๋ค. file-backed page๋ฅผ ํ ๋ ์ถ๊ฐํ๋๋ก ํ์!
bool supplemental_page_table_copy(struct supplemental_page_table *dst UNUSED,
struct supplemental_page_table *src UNUSED)
{
struct hash_iterator i;
hash_first(&i, &src->spt_hash);
while (hash_next(&i))
{
// src_page ์ ๋ณด
struct page *src_page = hash_entry(hash_cur(&i), struct page, hash_elem);
enum vm_type type = src_page->operations->type;
void *upage = src_page->va;
bool writable = src_page->writable;
/* 1) type์ด uninit์ด๋ฉด */
if (type == VM_UNINIT)
{ // uninit page ์์ฑ & ์ด๊ธฐํ
vm_initializer *init = src_page->uninit.init;
void *aux = src_page->uninit.aux;
vm_alloc_page_with_initializer(VM_ANON, upage, writable, init, aux);
continue;
}
/* 2) type์ด uninit์ด ์๋๋ฉด */
if (!vm_alloc_page(type, upage, writable)) // uninit page ์์ฑ & ์ด๊ธฐํ
// init์ด๋ aux๋ Lazy Loading์ ํ์ํจ
// ์ง๊ธ ๋ง๋๋ ํ์ด์ง๋ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ๋ฐ๋ก ๋ด์ฉ์ ๋ฃ์ด์ค ๊ฒ์ด๋ฏ๋ก ํ์ ์์
return false;
// vm_claim_page์ผ๋ก ์์ฒญํด์ ๋งคํ & ํ์ด์ง ํ์
์ ๋ง๊ฒ ์ด๊ธฐํ
if (!vm_claim_page(upage))
return false;
// ๋งคํ๋ ํ๋ ์์ ๋ด์ฉ ๋ก๋ฉ
struct page *dst_page = spt_find_page(dst, upage);
memcpy(dst_page->frame->kva, src_page->frame->kva, PGSIZE);
}
return true;
}
7) supplemental_page_table_kill
- ์ด ํจ์๋ ํ๋ก์ธ์ค๊ฐ ์ข ๋ฃ๋ ๋์ ์คํ๋ ๋ process_cleanup()์์ ํธ์ถ๋๋ค.
- ํ์ด์ง ํญ๋ชฉ๋ค์ ์ํํ๋ฉฐ ํ
์ด๋ธ ๋ด์ ํ์ด์ง๋ค์ ํ์
์ ๋ง๋ destroy ํจ์๋ฅผ ํธ์ถํ๋ค.
- destroy ๋งคํฌ๋ก๋ฅผ ์ฌ์ฉํ๋ฉด ํ์ด์ง ํ์ ์ ๋ฐ๋ผ์ uninit_destroy ํน์ anon_destroy ํจ์๊ฐ ํธ์ถ๋๋ค.
- ํ ๋น ๋ฐ์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ์์ ๊ฒฝ์ฐ์๋ ์ด ํ์ด์ง๋ก ์ธํด ์ ์ง๋๋ ๋ฆฌ์์ค๋ฅผ ํด์ ํด์ผ ํ์ง๋ง, ํ์ฌ๋ ๋ณ๋๋ก ํ ๋น ๋ฐ์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ์์ด์ ๋น์๋์๋ค.
- ์ฌ๊ธฐ์๋ hash table์ ๋๊ณ ์์ ์์๋ค๋ง ์ง์์ค์ผ ํ๋ค.
- hash_destroy ํจ์๋ฅผ ์ฌ์ฉํ๋ฉด hash๊ฐ ์ฌ์ฉํ๋ ๋ฉ๋ชจ๋ฆฌ(hash->bucket) ์์ฒด๋ ๋ฐํํ๋ฏ๋ก, hash_destroy๊ฐ ์๋ hash_clear๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค.
- Why? process๊ฐ ์คํ๋ ๋ hash table์ ์์ฑํ ์ดํ์ process_cleanup()์ด ํธ์ถ๋๋๋ฐ, ์ด๋๋ hash table์ ๋จ๊ฒจ๋๊ณ ์์ ์์๋ค๋ง ์ ๊ฑฐ๋์ด์ผ ํ๋ค.
๐๐ป hash table๊น์ง ์ง์๋ฒ๋ฆฌ๋ฉด ๋ง๋ค์๋ง์ ์ง์๋ฒ๋ฆฌ๋ ๊ฒ ๋๋ค.. process๊ฐ ์คํ๋ ๋ ๋น hash table์ด ์์ด์ผ ํ๋ฏ๋ก hash table์ ๋จ๊ฒจ๋๊ณ ์์ ์์๋ค๋ง ์ง์์ผ ํ๋ ๊ฒ์ด๋ค!
void supplemental_page_table_kill(struct supplemental_page_table *spt UNUSED)
{
/* TODO: Destroy all the supplemental_page_table hold by thread and
* TODO: writeback all the modified contents to the storage. */
hash_clear(&spt->spt_hash, hash_page_destroy); // ํด์ ํ
์ด๋ธ์ ๋ชจ๋ ์์๋ฅผ ์ ๊ฑฐ
}
void hash_page_destroy(struct hash_elem *e, void *aux)
{
struct page *page = hash_entry(e, struct page, hash_elem);
destroy(page);
free(page);
}
๐ก ์ด์ ํ๋ก์ ํธ 2์ ๋ชจ๋ ํ ์คํธ๋ฅผ ํต๊ณผํ๋ค. โ๐ป
- Test ๊ฒฐ๊ณผ (36 of 141 tests failed.)
pass tests/userprog/args-none
pass tests/userprog/args-single
pass tests/userprog/args-multiple
pass tests/userprog/args-many
pass tests/userprog/args-dbl-space
pass tests/userprog/halt
pass tests/userprog/exit
pass tests/userprog/create-normal
pass tests/userprog/create-empty
pass tests/userprog/create-null
pass tests/userprog/create-bad-ptr
pass tests/userprog/create-long
pass tests/userprog/create-exists
pass tests/userprog/create-bound
pass tests/userprog/open-normal
pass tests/userprog/open-missing
pass tests/userprog/open-boundary
pass tests/userprog/open-empty
pass tests/userprog/open-null
pass tests/userprog/open-bad-ptr
pass tests/userprog/open-twice
pass tests/userprog/close-normal
pass tests/userprog/close-twice
pass tests/userprog/close-bad-fd
pass tests/userprog/read-normal
pass tests/userprog/read-bad-ptr
pass tests/userprog/read-boundary
pass tests/userprog/read-zero
pass tests/userprog/read-stdout
pass tests/userprog/read-bad-fd
pass tests/userprog/write-normal
pass tests/userprog/write-bad-ptr
pass tests/userprog/write-boundary
pass tests/userprog/write-zero
pass tests/userprog/write-stdin
pass tests/userprog/write-bad-fd
pass tests/userprog/fork-once
pass tests/userprog/fork-multiple
pass tests/userprog/fork-recursive
pass tests/userprog/fork-read
pass tests/userprog/fork-close
pass tests/userprog/fork-boundary
pass tests/userprog/exec-once
pass tests/userprog/exec-arg
pass tests/userprog/exec-boundary
pass tests/userprog/exec-missing
pass tests/userprog/exec-bad-ptr
pass tests/userprog/exec-read
pass tests/userprog/wait-simple
pass tests/userprog/wait-twice
pass tests/userprog/wait-killed
pass tests/userprog/wait-bad-pid
pass tests/userprog/multi-recurse
pass tests/userprog/multi-child-fd
pass tests/userprog/rox-simple
pass tests/userprog/rox-child
pass tests/userprog/rox-multichild
pass tests/userprog/bad-read
pass tests/userprog/bad-write
pass tests/userprog/bad-read2
pass tests/userprog/bad-write2
pass tests/userprog/bad-jump
pass tests/userprog/bad-jump2
FAIL tests/vm/pt-grow-stack
pass tests/vm/pt-grow-bad
FAIL tests/vm/pt-big-stk-obj
pass tests/vm/pt-bad-addr
pass tests/vm/pt-bad-read
pass tests/vm/pt-write-code
FAIL tests/vm/pt-write-code2
FAIL tests/vm/pt-grow-stk-sc
pass tests/vm/page-linear
pass tests/vm/page-parallel
pass tests/vm/page-merge-seq
FAIL tests/vm/page-merge-par
FAIL tests/vm/page-merge-stk
FAIL tests/vm/page-merge-mm
pass tests/vm/page-shuffle
FAIL tests/vm/mmap-read
FAIL tests/vm/mmap-close
FAIL tests/vm/mmap-unmap
FAIL tests/vm/mmap-overlap
FAIL tests/vm/mmap-twice
FAIL tests/vm/mmap-write
pass tests/vm/mmap-ro
FAIL tests/vm/mmap-exit
FAIL tests/vm/mmap-shuffle
FAIL tests/vm/mmap-bad-fd
FAIL tests/vm/mmap-clean
FAIL tests/vm/mmap-inherit
FAIL tests/vm/mmap-misalign
FAIL tests/vm/mmap-null
FAIL tests/vm/mmap-over-code
FAIL tests/vm/mmap-over-data
FAIL tests/vm/mmap-over-stk
FAIL tests/vm/mmap-remove
pass tests/vm/mmap-zero
FAIL tests/vm/mmap-bad-fd2
FAIL tests/vm/mmap-bad-fd3
FAIL tests/vm/mmap-zero-len
FAIL tests/vm/mmap-off
FAIL tests/vm/mmap-bad-off
FAIL tests/vm/mmap-kernel
FAIL tests/vm/lazy-file
pass tests/vm/lazy-anon
FAIL tests/vm/swap-file
FAIL tests/vm/swap-anon
FAIL tests/vm/swap-iter
pass tests/vm/swap-fork
pass tests/filesys/base/lg-create
pass tests/filesys/base/lg-full
pass tests/filesys/base/lg-random
pass tests/filesys/base/lg-seq-block
pass tests/filesys/base/lg-seq-random
pass tests/filesys/base/sm-create
pass tests/filesys/base/sm-full
pass tests/filesys/base/sm-random
pass tests/filesys/base/sm-seq-block
pass tests/filesys/base/sm-seq-random
pass tests/filesys/base/syn-read
pass tests/filesys/base/syn-remove
pass tests/filesys/base/syn-write
pass tests/threads/alarm-single
pass tests/threads/alarm-multiple
pass tests/threads/alarm-simultaneous
pass tests/threads/alarm-priority
pass tests/threads/alarm-zero
pass tests/threads/alarm-negative
pass tests/threads/priority-change
pass tests/threads/priority-donate-one
pass tests/threads/priority-donate-multiple
pass tests/threads/priority-donate-multiple2
pass tests/threads/priority-donate-nest
pass tests/threads/priority-donate-sema
pass tests/threads/priority-donate-lower
pass tests/threads/priority-fifo
pass tests/threads/priority-preempt
pass tests/threads/priority-sema
pass tests/threads/priority-condvar
pass tests/threads/priority-donate-chain
FAIL tests/vm/cow/cow-simple
36 of 141 tests failed.
'Computer Science' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Pintos-KAIST] Project 3 :: Memory Mapped Files (2) | 2023.05.22 |
---|---|
[Pintos-KAIST] Project 3 :: Memory Management (1) | 2023.05.16 |
[Pintos-KAIST] Project 2 :: System Calls - 3 (File System), User Memory (0) | 2023.05.16 |