본문 바로가기
개발일지/PintOS

pintos - virtual memory(5)

by Peter.JH 2023. 12. 22.
728x90
반응형

Supplemental Page Table - Revisit

bool supplemental_page_table_copy (struct supplemental_page_table *dst,
    struct supplemental_page_table *src);

 

git_book 설명:

보조 페이지 테이블을 src에서 dst로 복사합니다. 이 함수는 자식이 부모의 실행 컨텍스트를 상속해야 할 때 사용됩니다(예: fork()). src의 보충 페이지 테이블에 있는 각 페이지를 반복하고 dst의 보충 페이지 테이블에 있는 항목의 정확한 복사본을 만듭니다. 초기화되지 않은 페이지를 할당하고 즉시 청구해야 합니다.

 

supplemental_page_table_copy함수 호출하는 곳:

 

 

hash.c에 있는 hash_first 함수를 참고해 만들 수 있다. 

   struct hash_iterator i;

   hash_first (&i, h);
   while (hash_next (&i))
   {
   struct foo *f = hash_entry (hash_cur (&i), struct foo, elem);
   ...do something with f...
   }

 

/* 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;
		vm_initializer *init = parent_page->uninit.init;
		void *aux = parent_page->uninit.aux;

		if (parent_page->operations->type == VM_UNINIT) {
			if (!vm_alloc_page_with_initializer(type, upage, writable, init, aux)) {
				return false;
			}
		}
		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;
}

 

원본 테이블(src)의 각 페이지를 순회하면서 동일한 페이지를 대상 테이블(dst)에 생성하고, 필요한 경우 원본 페이지의 데이터를 대상 페이지에 복사한다.

1. hash_first와 hash_next를 사용하여 원본 테이블의 각 페이지를 순회한다.

2. hash_entry를 사용하여 현재 페이지의 정보를 가져온다.

3. 페이지의 타입, 주소, 쓰기 가능 여부, 초기화 함수, 보조 데이터 등을 저장한다.

4. *페이지의 타입이 VM_UNINIT(초기화되지 않은)인 경우, 초기화 함수와 보조 데이터를 사용하여 대상 테이블에 새로운 페이지를 생성한다.

5. *페이지의 타입이 VM_UNINIT이 아닌 경우, 대상 테이블에 새로운 페이지를 생성하고, 해당 페이지를 claim(메모리를 할당)한다. 그 다음 원본 페이지의 데이터를 대상 페이지에 복사한다.

6. 모든 페이지가 성공적으로 처리되면 true를 반환하고, 그렇지 않으면 false를 반환한다. 

 

* 페이지의 타입이 VM_UNINIT(초기화되지 않은)인 경우와 아닌 경우를 나눠서 처리하는 이유는 두 타입의 페이지가 메모리에 로드되는 방식이 다르기 때문이다.

VM_UNINIT 타입의 페이지는 아직 메모리에 로드되지 않은 상태를 나타낸다. 이런 페이지는 디스크에 저장되어 있거나, 아직 생성되지 않았을 수 있다. 이런

페이지를 메모리에 로드하려면 초기화 함수와 보조 데이터를 사용하여 페이지를 생성하고 초기화해야 한다. (이 과정에서 초기화 함수는 페이지의 데이터를 생성하거나 디스크에서 불러오는 등의 역할)

반면, VM_UNINIT이 아닌 페이지는 이미 메모리에 로드된 상태를 나타낸다. 이런 페이지를 다른 위치에 복사하려면 단순히 페이지의 데이터를 복사하면 된다. 이 과정에서 메모리 할당과 데이터 복사가 이루어진다. 

 

 

void supplemental_page_table_kill (struct supplemental_page_table *spt);

 

 git_book 설명:

 

보조 페이지 테이블이 보유하고 있던 모든 리소스를 해제합니다. 이 함수는 프로세스가 종료될 때 호출됩니다(userprog/process.c의 process_exit()). 페이지 항목을 반복하고 테이블의 페이지에 대해 destroy(page)를 호출해야 합니다. 이 함수에서 실제 페이지 테이블(pml4)과 물리적 메모리(할당된 메모리)는 걱정할 필요가 없습니다. 호출자는 보조 페이지 테이블이 정리된 후 이를 정리하기 때문입니다.

 

void
page_kill (struct hash_elem *e, void *aux) {
	struct page *page = hash_entry(e, struct page, hash_elem);
	destroy(page);
	free(page);
}

/* Free the resource hold by the supplemental page 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, page_kill);
}

 

해시 테이블은 남기고 해시 테이블의 모든 요소를 제거하는 hash_clear함수를 써서 수행하면 된다. (해시 테이블까지 삭제하면 만들자마자 지워버리게 되는 셈이다)

 

여기까지 했을 때 read관련된 테이스가 모두 fail했다... 

 

read에서 checkadress가 문제였다. 

void check_address(void *addr) {
	struct thread *t = thread_current();
	if (!is_user_vaddr(addr) || addr == NULL || pml4_get_page(t->pml4 , addr) == NULL) {
		exit(-1);
	}
}

 

문제점을 찾아보시오~!!

.

.

.

.

.

 

vm에서는 page fault가 발생한다. 아직 메모리에 로드되지 않았을 경우도 있기에 위 함수에서 'pml4_get_page(t->pml4 , addr) == NULL' 경우를 제외시켜줘야 한다. 

 

여기까지 했을 때 테스트 결과 userprog 테스트가 모두 통과하게 된다.

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

 

728x90
반응형

'개발일지 > PintOS' 카테고리의 다른 글

pintos - virtual memory(7)  (0) 2023.12.25
pintos - virtual memory(6)  (0) 2023.12.22
pintos - virtual memory(4)  (0) 2023.12.20
pintos - virtual memory(3)  (0) 2023.12.19
pintos - Virtual Memory(1)  (0) 2023.12.14