[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

 

[Linux] pageflags로 살펴본 메모리의 일생

Linux: 2.6.39-rc3arch: x86_64커널은 물리 메모리를 (페이지 단위로) 관리하기 위해 page 구조체를 사용한다.page 구조체에는 해당 페이지 프레임에 관한 정보가 저장되어 있는데그 중 가장 중요한 정보는 바로 페이지가 현재 어떠한 상태에 있는지를 나타내는 flags 필드이다.(추가적으로 flags 필드에는 시스템의 메모리 구성에 따라

egloos.zum.com

 

+ Recent posts