본문 바로가기

TIL (Today I Learned)

3/29 (금) TIL - fork 테스트케이스까지 모두 통과!

728x90

 

 

! 오늘의 알고리즘 

백준 14502번 연구소

bfs 문제지만 접근이 좀 어려웠다. 조합을 사용해야 한다는 힌트를 듣고 풀 수 있었다.

브루트포스 등의 모든 경우에 접근해야 하는 경우, 조합이나 순열을 사용해야 하는게 생각이 잘 안 떠오르네...

 

 

! 오늘의 실수

 

palloc_get_page() 했던 메모리에 대해 free()로 메모리 해제를 해주어 오류가 발생... 미처 깨닫지 못 해 몇 십분 흘러버려...

 

! 오늘의 무지함

 

 1  hash 시스템, 사용법에 대해 무지했다. 어제 TIL에 썼던거 같은데 - 왜 insert 해준적 없는 page에 대한 hash_find()가 가능한가? 이 질문에 대한 답을 얻었다.

 

전체 질문 채널에 질문했는데 다른 정글러분께서 설명해주셨다!

 

hash_init() 할 때 설정해주었던 보조 함수들 중 page_hash() 라는 함수가 페이지의 va를 기준으로 hash 인자를 설정해주었다. Gitbook에 있던 함수라서 제대로 파악하지 않고 작성했던 것이 패착이었다.

저 page_hash()를 이용해 insert 하기 때문에 비어있는 page도 va만 설정해주면 va와 같은 값의 hash_elem을 반환받을 수 있었다.

 

 2  system call에서의 오류

project 2 할 때, 시스템콜 중 파일 시스템에 관련된 함수를 작성하면서 is_kernel_addr 면 return, addr == NULL 이면 return 등등 주소, FD와 관련된 예외처리를 해주었다.

이 중 pml4_get_page(addr) == NULL 이면 사용할 수 있는 페이지가 없으니 NULL을 반환했었다.

여기서 문제가 생겼다. 우리는 lazy loading을 구현하고 있기 때문에 파일을 open 하자마자 read를 하게 되면 아직 물리 메모리에 파일이 적재되지 않은 상태인데, 이 상태를 NULL로 반환을 해버리니 파일을 읽을 수 없었다.

 

지금은 임시방편으로 pml4_get_page(addr) == NULL 구문을 조건문에서 제거했더니 read, close 등이 통과가 되었다.

그렇지만 의문인게 NULL을 반환한 경우 page_fault를 호출해야 하는 것이 아닌가?

pml4_get_page()가 NULL을 반환했다면, 페이지에 대한 물리 메모리가 적재되지 않았다는 뜻인지, 페이지 테이블 엔트리가 존재하지 않는다는 뜻인지가 헷갈린다...

 

2-1 해결

여러 조건문을 조합한 결과

아래 수도코드와 비슷하게 작성해서 디버깅을 시도했다.

if pml4_get_page(addr) == NULL
    page = spt_find_page(addr)
    if page == NULL
    	printf("find FAIL")
    else
    	printf("find SUCC")

 

그 결과

  • pml4에서 page를 받아오지 못 하는 경우 -> 매핑된 물리 메모리가 없음
  • spt에서 page를 받아오면 frame이 NULL
  • spt에서 page를 받아오지 못하면 이상한 경우

위의 세 가지 정보를 얻었다.

 

해결책은 알았는데 syscall.c에서 vm.h를 선언해 사용해도 되는지, 너무 하드코딩이 아닌지 고민했는데 다른 분들 코드를 살펴보니 다들 쓰셨길래 안심하고 사용했다 ㅎㅎ

 

해결은 page를 spt에서 찾지 못 했을때만 exit를 호출하고, 이외의 경우 그러니까 물리 메모리만 없는 경우에는 페이지 폴트를 호출하겠거니 생각하는 중이다. 

여기에서 vm_do_claim_page()를 호출해 물리 메모리를 적재해야하나 생각했지만, 시스템콜에서 너무 많은 일을 해결하는 것 같아 적절하지 않다고 생각했다.

 

 

 

 

! 오늘의 주저리

 

코드를 열심히 짜고, 실패하고, 참고하고 이 사이클을 계속 반복중이다. 참고하지 않고 pass를 많이 보고 싶은데, 좀 아쉽지만 그래도 우리가 접근하는 방법이 아주 다른 방향이 아니라는 것을 중간중간 확인받고 있다고 생각한다.

 

내일 고민할거

지금 page_fault에서 kill() 대신 exit(-1)를 호출하게 바꿨는데 지금 fail은 발생하지 않지만, 원래 kill을 호출하는 것이 올바른(?) 방법이 아닌가 고민중이다. 팀원들과 상의해보고, 변경 후 make check도 돌려봐야겠다.

 

오늘은 진도가 많이 나갔다. 기분이 좋다!

오늘의 결과

 

구현 진도 뿐만 아니라 전체적인 구조에 대한 이해도 더 늘었다고 생각한다. 어떻게 구현했고, 어디서 어느 함수를 호출하는지 좀 더 익혀야한다. 파이팅