kmalloc vs vmalloc 비교
커널에서 메모리를 할당할 때 요구 메모리 사이즈와 성능 사이에서 고려할 API가 다음 두 개가 있고 특징에 따라 구분하여 사용하여야 한다.
- 할당 크기 등은 slab, slub 및 slob의 단위가 모두 다르며 최근에 가장 많이 사용하는 slub을 기준으로 나타낸다.
kmalloc의 특징
연속된 물리 메모리를 연속된 가상 공간에 매핑하여 할당 받는다.
- 요구 메모리가 kmalloc 캐시 최대 크기 이하인 경우 kmalloc 캐시에서 slub object를 할당받는다.
- 예) 4K 페이지: kmalloc 캐시(slub) 최대 크기=8K (2개 페이지)
- 요구 메모리가 kmalloc 최대 크기보다 큰 경우 버디 시스템을 사용하여 할당한다.
- 연속된 물리 메모리를 연속된 가상 주소 공간에 매핑하여 할당 받는다. (DMA 디바이스에서 사용 가능)
- 이미 사전에 1:1 매핑된 lowmem(ZONE_DMA 및 ZONE_NORMAL) 공간을 사용하므로 vmalloc()에 비해 성능이 빠르다.
- 단점으로는 물리적으로 연속된 공간을 할당해야 하므로 페이지 관리 측면에서 단편화 관리에 어려움이 발생한다
- GFP_ATOMIC 플래그를 사용하는 경우 슬립되지 않으므로 인터럽트 핸들러에서도 사용될 수 있다.
vmalloc의 특징
단편화되어 연속되지 않는 여러 개의 페이지들을 모아 연속된 가상 메모리 공간에 매핑하여 할당받는다.
- kmalloc()과 다르게 여러 개의 조각난 연속된 물리 메모리를 모아서 관리하고 이들을 별도의 공간(커널은 vmalloc address space, userland는 user space address)에 매핑하여 사용하므로 관리 요소가 증가되고 각 cpu의 tlb 플러쉬가 필요하므로 cpu core가 많은 경우 사용에 어려움이 있다.
- 커널은 VMALLOC address space를 통해 연속된 가상 주소 메모리를 제공하는데 이 공간은 아키텍처에 따라 다르다.
- arm64: kernel 매핑 공간의 약 절반 (커널 빌드 옵션마다 위치가 달라진다.)
- arm: 240M (0xf000_0000 ~ 0xff00_0000)
- 매핑 시 vmalloc address space 공간을 사용하는 vmap() 매핑 함수를 사용한다.
- 커널은 VMALLOC address space를 통해 연속된 가상 주소 메모리를 제공하는데 이 공간은 아키텍처에 따라 다르다.
- 대용량의 커널 메모리가 필요하고 lowmem 부족으로 인한 압박이 예상되면서 속도는 약간 느려도 무방한 경우 페이지의 단편화를 방지하기 위해 vmalloc()을 사용하는 것이 좋다.
- 연속되지 않은 물리 주소 블록들을 연속된 가상 주소로 매핑하기 위해 기존 커널은 리스트에 각각의 vma_area(한 블럭의 매핑 장보)를 추가하여 관리했었다. 비록 커널이 많은 수의 vmap_area를 사용하지 않았지만 커다란 application에서 수백 또는 수천 개의 vmp_area를 검색하여 성능이 저하되는 것을 막기 위해 커널 2.6에서 레드 블랙 트리를 사용하여 관리하도록 바뀌었다.
- 슬립될 수 있으므로 인터럽트 핸들러에서 사용되면 안된다.
위와 같은 이유로 대부분의 커널 코드에서는 kmalloc()을 더 많이 사용하고 다음과 같은 사용 목적으로 vmalloc()을 사용한다.
- swap area용 자료구조
- 모듈 공간 할당
- 일부 디바이스 드라이버 등
kzalloc() vs vzalloc()
- kzalloc() 함수는 kmalloc() 함수로 할당 받은 메모리를 0으로 초기화한다.
- vzalloc() 함수는 vmalloc() 함수로 할당 받은 메모리를 0으로 초기화한다.
참고
- Slab Memory Allocator -1- (구조) | 문c
- Kmalloc vs Vmalloc | 문c – 현재 글
- Kmalloc | 문c
- Vmalloc | 문c
- Vmap() | 문c
- gfp 플래그 | 문c