[0]
Linux kernel의 page 구조체에 대해서 알아본다.
[1]
우선, page 구조체는 가상 메모리가 아니라 물리 메모리를 관리하기 위해 존재한다. page 구조체는 물리 메모리의 모든 page마다 하나씩 할당된다. 즉 물리 메모리가 4GB, page 크기가 4KB라면, 4GB/4KB = 1024 * 1024개의 page 구조체 인스턴스가 생성된다. 커널은 이 page 구조체 인스턴스를 통해, 어떤 물리 메모리 영역이 free인지, 혹은 어떤 용도로 할당되어있는지를 파악할 수 있다.
[2]
page 구조체의 전체 코드는 여기에서 확인할 수 있다. 하지만 처음에는 우선 전체 멤버를 보기보다, 핵심을 추려낸 아래 코드를 보자.
struct page {
unsigned long flags; /* Atomic flags, some possibly
* updated asynchronously */
//
//... I skipped complicated Unions here
//
/* Usage count. *DO NOT USE DIRECTLY*. See page_ref.h */
atomic_t _refcount;
/*
* On machines where all RAM is mapped into kernel address space,
* we can simply calculate the virtual address. On machines with
* highmem some memory is mapped into kernel virtual memory
* dynamically, so we need a place to store that address.
* Note that this field could be 16 bits on x86 ... ;)
*
* Architectures with slow multiplication can define
* WANT_PAGE_VIRTUAL in asm/page.h
*/
#if defined(WANT_PAGE_VIRTUAL)
void *virtual; /* Kernel virtual address (NULL if
not kmapped, ie. highmem) */
#endif /* WANT_PAGE_VIRTUAL */
}
비교적 간단한 구조체임을 알 수 있다. 핵심 멤버 변수들을 살펴보자.
1) unsigned long flags
이 page의 상태를 나타내는 멤버이다. 사실상 이 구조체의 가장 핵심이라고 볼 수 있다. flag들에 대해서는 아래 [3]에서 다시 다룬다.
2) atomic_t refcount
이름에서 유추할 수 있듯이, 해당 page에 대한 reference counter를 나타낸다.
3) void *virtual
현재 매핑되어 있는 가상 주소를 가리킨다. 매핑되어있지 않다면, 물론 NULL값을 갖게 된다. 아키텍처에 따라 선언되지 않을 수도 있다.(물리 주소로부터 가상 주소를 쉽게 계산할 수 있을 경우 등, 코드 주석 참고)
이 외에, 전체 구조체 코드에서는 union들이 상당히 큰 영역을 차지함을 알 수 있다. 예를 들어, page 캐쉬 혹은 익명 페이지는 union안의 다음의 구조체로 선언되어 있다.
struct { /* Page cache and anonymous pages */
/**
* @lru: Pageout list, eg. active_list protected by
* pgdat->lru_lock. Sometimes used as a generic list
* by the page owner.
*/
struct list_head lru;
/* See page-flags.h for PAGE_MAPPING_FLAGS */
struct address_space *mapping;
pgoff_t index; /* Our offset within mapping. */
/**
* @private: Mapping-private opaque data.
* Usually used for buffer_heads if PagePrivate.
* Used for swp_entry_t if PageSwapCache.
* Indicates order in the buddy system if PageBuddy.
*/
unsigned long private;
};
이 외에도 slab/slob/slub page, ZONE_DEVICE page 등등이 선언되어 있다.
[3]
page flags는 이 페이지의 상태를 나타낸다. 이를 살펴보는 것으로 커널의 물리 페이지 관리에 대해서 충분히 이해할 수 있다.
1) PG_reserved
특별한 목적을 가진 페이지들. 예를 들어 커널 text, 디바이스 메모리 등등. 일반적인 목적으로 접근할 수 없는 페이지들이며, 해제되거나 swapping 되지 않는다.
2) PG_slab
slab allocator(kmalloc 등)을 통해 할당받은 페이지
3) PG_uptodate
페이지 컨텐츠가 최신임. 읽기 작업이 수행되면 이 플래그가 set된다.
4) PG_dirty
페이지 컨텐츠가 최신이 아님. 쓰기 작업이 수행되면 이 플래그가 set된다.
5) PG_mappedtodisk
페이지가 디스크의 블록에 매핑되어 있음. 이 플래그가 set되어 있어야 swap-out이 가능하다.
6) PG_writeback
페이지가 write-back을 수행 중
이 외에도 다양한 플래그들이 존재한다. 이 소스에서 확인 가능하다.
[참고]
http://egloos.zum.com/studyfoss/v/5512112
'Computer Science > Kernel' 카테고리의 다른 글
printf 함수 실행 분석하기 (0) | 2020.08.22 |
---|---|
Linux kernel의 Superblock 구조체 (0) | 2020.06.02 |
Ch.11 Timers and Time Management (0) | 2017.08.27 |
Ch.10 Kernel Synchronization Methods 커널 동기화 방법 (0) | 2017.08.24 |
CH.9 An Introduction to Kernel Synchronization (0) | 2017.08.24 |