본문 바로가기
Today I learned

리눅스 물리메모리 관리구조

by soheemon 2019. 5. 21.

※[리눅스 커널 내부구조]책을 읽고 요약한 내용입니다.

Node

리눅스에서 접근속도가 같은 메모리의 집합을 뱅크라고 부른다.

UMA 구조라면 한개의 뱅크가 존재하고, NUMA구조라면 복수개의 뱅크가 존재하게 된다.

리눅스에서는 뱅크를 표현하는 구조가 노드이다.

 

UMA구조의 시스템이라면 한개의 노드가 존재하며, 이는 config_page_data를 통해 접근 가능하다.

NUMA구조의 시스템이라면 복수개의 노드가 존재 하며 리스트를 통해 관리된다. pgdat_list라는 이름의 배열을 통해 접근이 가능하다.

 

리눅스는 UMA/NUMA 구조와 관계없이 노드라는 일관된 자료구조를 통해 전체 물리메모리를 접근 할 수 있다.

 

하나의 노드는 pg_data_t 구조체를 통해 표현된다.

pg_data_t 구조체는 아래와같은 변수를 포함하고 있다.

  • node_present_pages: 해당 노드에 속해있는 물리메모리의 실제 양
  • node_start_pfn: 해당 물리메모리가 메모리맵의 몇번지에 위치하고 있는지를 나타내기 위한 변수
  • node_zones: zone 구조체를 담기위한 배열
  • nr_zones: zone의 개수를 담는 변수

리눅스가 물리메모리 할당요청을 받게되면 되도록 할당을 요청한 태스크가 수행되고 있는 CPU와 가까운 노드에서 메모리를 할당하려한다.

또한 리눅스는 태스크를 수행할 때, 이전에 수행했었던 CPU를 다시 수행하도록 하기때문에 보다 높은 성능을 얻을 수 있게 된다.

 

Zone

 

 

일부 ISA 버스기반 디바이스의 경우 정상적인 동작을 위해서는 반드시 물리메모리중 하위16MB 부분을 할당 해 줘야 하는 경우가 있다.(비록 최근 점차 사용하지 않은 추세지만 리눅스는 ISA디바이스 사용여부와 관계없이 원활히 수행되도록 설계되어있다.)

이를위해 노드에 존재하는 물리 메모리중 하위16MB 부분을 따로 관리 할 수 있게 자료구조를 만들어 놓았다.

이 자료구조를 zone이라 부른다.

 

DMA, Normal, HighMem 세개의 zone이 한 시스템에 전부 존재하는것은 아니다. 예를들어 64MB/SDRAM 의 ARM CPU 시스템이라면 node한개, zone 한개가 존재하게 된다.

 

각 zone은 자신에게 속해있는 물리메모리를 관리하기 위해 zone구조체를 사용한다.

이 구조체에는

  • 해당 zone이 속해있는 물리메모리의 시작 주소와 크기
  • 버디 할당자가 사용 할 free_area 구조체 변수
  • wait_table 프로세스가 zone에 메모리 할당요청을 했지만 free 페이지가 부족하여 할당해주지 못한경우 프로세스를 wait_que에 넣고 해싱하여 wait_table 변수가 가리키게 한다.
  • watermark와 vm_stat을 통해 남아있는 빈 공간이 부족한경우 적절한 메모리 해제정책을 결정하게 된다.

PageFrame

각각zone이 관리하는 물리메모리의 최소단위를 페이지프레임이라고 한다.

페이지 프레임은 page라는 이름의 구조체에 의해 관리된다.

모든 페이지 프레임은 page 구조체가 존재하며 때문에 리눅스는 시스템 내의 모든 물리메모리에 접근할 수 있다.

이는 시스템 부팅시 구축되어 물리메모리 특정 위치에 저장되며, mem_map이라는 전역배열을 통해 접근 할 수 있다.

 

리눅스가 물리메모리를 할당하는 방법

물리메모리 할당의 최소단위는 페이지프레임 단위로 결정되며 이는 4KB이다.(8KB, 2MB등 기본 크기 설정 가능)

 

두가지 경우를 가정해보자.

1) 4KB보다 작은 크기를 요청하는 경우

=> 이경우 페이지프레임보다 작은 크기를 요청하기 때문에 내부 단편화 문제가 발생할 수 있다.

=> 슬랩 할당자 도입

2) 4KB보다 큰 공간을 요청하는 경우

=> 버디할당자를 도입하여 메모리 관리 부하와 외부 단편화를 줄일 수 있다.

 

버디할당자

zone당 하나씩 존재하는 zone구조체의 free_area[]배열을 통해 구축된다.

free_area[] 배열에 포함된 엔트리는 free_area 구조체이며, 이 구조체는 free_list와 map 필드를 갖는다.

#define MAX_ORDER 10 
struct zone{
	...
	struct free_area	free_area[MAX_ORDER];	//버디할당자 관리용배열
}
struct free_area{
	struct list_head	free_list;				//free페이지 프레임을 list로 관리
    unsigned long		*map;					//페이지 상태를 비트맵으로 관리
}

free_area 배열은 10개의 엔트리를 가지며,

0-9까지 각각의 숫자를 해당 free_area가 관리하는 할당의 크기를 나타낸다.

0인경우 2^0 = 1개의 페이지 프레임이 할당관리영역

1인경우 2^1 = 2개의 페이지 프레임이 할당관리영역

 

버디는 2의 정수승 개수의 페이지 프레임을 할당해주며(4KB, 8KB, 16KB...) 최대 할당 크기는 4MB(2^10 x 4KB)이다.

 

free_area 구조체는 내부의 free_list 변수를 통해 자신에게 할당된 free페이지 프레임을 list로 관리한다.

또한 map이라는 변수를 통해 자신이 관리하는 페이지 상태를 map변수를 통해 비트맵으로 관리한다.

댓글