나는 왜 syn-read, syn-write이 안되는가...!!!!
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
pass tests/vm/pt-grow-stack
pass tests/vm/pt-grow-bad
pass 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
pass 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
FAIL tests/vm/mmap-ro
FAIL tests/vm/mmap-exit
FAIL tests/vm/mmap-shuffle
pass 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
pass tests/vm/mmap-bad-fd2
pass tests/vm/mmap-bad-fd3
pass 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
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
31 of 141 tests failed.
문제점:
syn-read test에서 fork -> exec -> write 를 10번 한후 exec -> open을 할려고 했을 때 page 가 NULL이여서 exit한다.
/* Copy supplemental page table from src to dst */
bool
supplemental_page_table_copy (struct supplemental_page_table *dst UNUSED,
struct supplemental_page_table *src UNUSED) {
struct hash_iterator i;
struct hash *parent_hash = &src->spt_hash;
struct hash *child_hash = &dst->spt_hash;
hash_first(&i, parent_hash);
while (hash_next(&i))
{
struct page *parent_page = hash_entry(hash_cur(&i), struct page, hash_elem);
enum vm_type type = parent_page->operations->type;
if (type == VM_UNINIT)
{
struct uninit_page *uninit_page = &parent_page->uninit;
struct segment *file_loader = (struct file_loader *)uninit_page->aux;
struct segment *new_file_loader = malloc(sizeof(struct segment));
memcpy(new_file_loader, uninit_page->aux, sizeof(struct segment));
new_file_loader->file = file_duplicate(file_loader->file);
vm_alloc_page_with_initializer(uninit_page->type, parent_page->va, true, uninit_page->init, new_file_loader);
vm_claim_page(parent_page->va);
free(new_file_loader);
}
else
{
vm_alloc_page(parent_page->operations->type, parent_page->va, true);
vm_claim_page(parent_page->va);
memcpy(parent_page->va, parent_page->frame->kva, PGSIZE);
}
}
return true;
}
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)) {
struct page *parent_page = hash_entry (hash_cur (&i), struct page, hash_elem);
enum vm_type type = page_get_type(parent_page);
void *upage = parent_page->va;
bool writable = parent_page->writable;
vm_initializer *init = parent_page->uninit.init;
void *aux = parent_page->uninit.aux;
if (parent_page->operations->type == VM_UNINIT) {
struct segment *file_loader = (struct segment *)aux;
struct segment *new_file_loader = malloc(sizeof(struct segment));
memcpy(new_file_loader, aux, sizeof(struct segment));
new_file_loader->file = file_duplicate(file_loader->file);
if (!vm_alloc_page_with_initializer(type, upage, writable, init, new_file_loader)) {
free(new_file_loader);
return false;
}
if (!vm_claim_page(upage)) {
free(new_file_loader);
return false;
}
free(new_file_loader);
}
else {
if (!vm_alloc_page(type, upage, writable)) {
return false;
}
if (!vm_claim_page(upage)) {
return false;
}
struct page *child_page = spt_find_page(dst, upage);
memcpy(child_page->frame->kva, parent_page->frame->kva, PGSIZE);
}
}
return true;
}
위 두 개의 코드를 참고해 supplemental_page_table_copy 함수를 수정했다....
my code
/* Copy supplemental page table from src to dst */
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)) {
struct page *parent_page = hash_entry (hash_cur (&i), struct page, hash_elem);
enum vm_type type = page_get_type(parent_page);
void *upage = parent_page->va;
bool writable = parent_page->writable;
if (parent_page->operations->type == VM_UNINIT) {
vm_initializer *init = parent_page->uninit.init;
void *aux = parent_page->uninit.aux;
struct segment *file_loader = (struct segment *)aux;
struct segment *new_file_loader = malloc(sizeof(struct segment));
memcpy(new_file_loader, aux, sizeof(struct segment));
new_file_loader->file = file_duplicate(file_loader->file);
if (!vm_alloc_page_with_initializer(type, upage, writable, init, aux)) {
free(new_file_loader);
return false;
}
if (!vm_claim_page(upage)) {
free(new_file_loader);
return false;
}
free(new_file_loader);
}
else {
if (!vm_alloc_page(type, upage, writable)) {
return false;
}
if (!vm_claim_page(upage)) {
return false;
}
struct page *child_page = spt_find_page(dst, upage);
memcpy(child_page->frame->kva, parent_page->frame->kva, PGSIZE);
}
}
return true;
}
많은 것이 추가되었지만 psss에 제일 큰 영향이 있는 부분은
이 부분이다....
supplemental_page_table_copy
왜 UNINIT TYPE일 때 vm_claim_page를 해줘야 할까?
`vm_claim_page()` 함수를 호출하는 것은 해당 페이지가 필요하다는 것을 시스템에 알리는 역할을 한다. 이 함수를 호출하면, 가상 주소(va)에 해당하는 페이지를 찾아 이 페이지를 'claim'하게 된다. 이는 새로운 프레임을 가져와 페이지와 프레임을 연결하고, 페이지 테이블 엔트리를 업데이트하여 페이지의 가상 주소를 프레임의 물리 주소에 매핑하는 과정을 포함한다.
`parent_page->operations->type == VM_UNINIT`일 때 `vm_claim_page()`를 호출하는 이유는 VM_UNINIT 타입의 페이지는 아직 메모리에 로드되지 않은 상태를 나타내므로, 이 페이지를 사용하기 위해서는 먼저 메모리에 로드해야 하기 때문이다. 따라서 `vm_claim_page()`를 호출하여 해당 페이지를 메모리에 로드하게 된다. 이 과정을 통해 VM_UNINIT 타입의 페이지는 메모리에 로드되어 실제로 사용할 수 있는 상태가 된다.
이는 페이지 테이블의 복사 과정에서 필요한 단계로, 복사 대상인 원본 페이지 테이블의 페이지들이 모두 메모리에 로드되어야만, 새로운 페이지 테이블로의 복사가 가능하다.
결국 vm_claim_page() 통해 ANON타입으로 바뀌게 되는데 이는 나중에 swap 상황에서 문제가 생길 가능성이 있어 보인다... 수정이 꼭 필요해 보인다.
우선 현 상황
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
pass tests/vm/pt-grow-stack
pass tests/vm/pt-grow-bad
pass 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
pass 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
FAIL tests/vm/mmap-ro
FAIL tests/vm/mmap-exit
FAIL tests/vm/mmap-shuffle
pass 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
pass tests/vm/mmap-bad-fd2
pass tests/vm/mmap-bad-fd3
pass 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
29 of 141 tests failed.
'개발일지 > PintOS' 카테고리의 다른 글
pintos......... (0) | 2023.12.28 |
---|---|
pintos - virtual memory(7) (0) | 2023.12.25 |
pintos - virtual memory(5) (0) | 2023.12.22 |
pintos - virtual memory(4) (0) | 2023.12.20 |
pintos - virtual memory(3) (0) | 2023.12.19 |