Post

[Linux] Slab Memory Allocator

개요

Linux Kernel에서 Slab Memory Allocator란 user단에서 ptmalloc과 같이 Kernel에서 사용되는 동적 메모리 할당자 입니다. ex) kmalloc()

  • Slab Cache: 자주 사용되는 크기에 대한 동적 메모리를 미리 확보하고 관리하는 역할
  • Slab Object: Slab Cache가 할당해 놓은 메모리 블록.
  • Slab Page: Slab Object로 구성된 페이지

종류

Slab Memory Allocator에는 크게 다음과 같이 3종류가 사용되고 있습니다. 이 중, 해당 포스터에서 별도의 언급이 없으면 Slab Memory AllocatorSlub를 의미한다고 생각하시면 됩니다.

  1. Slab
  2. Slub
  3. Slob

💡 Linux Kernel에서 Slub가 Default로 사용되기 때문에 해당 내용만 다루겠습니다!

kmalloc 할당 과정

kmalloc

해당 함수는 다음과 같이 정의되어 있습니다. 할당하는 size가 KMALLOC_MAX_CACHE_SIZE보다 크다면 kmalloc_large 함수가 호출되고 아니라면 kmalloc_trace 함수가 호출됩니다.

💡 kmalloc_index 함수는 size의 크기에 따라 index를 반환해주는 함수 입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
static __always_inline __alloc_size(1) void *kmalloc(size_t size, gfp_t flags)
{
	if (__builtin_constant_p(size) && size) {
		unsigned int index;

		if (size > KMALLOC_MAX_CACHE_SIZE)
			return kmalloc_large(size, flags);

		index = kmalloc_index(size);
		return kmalloc_trace(
				kmalloc_caches[kmalloc_type(flags, _RET_IP_)][index],
				flags, size);
	}
	return __kmalloc(size, flags);
}

kmalloc_trace

kmalloc_trace 함수는 다음과 같이 slab_alloc_node 함수를 호출합니다.

1
2
3
4
5
6
7
8
9
10
11
void *kmalloc_trace(struct kmem_cache *s, gfp_t gfpflags, size_t size)
{
	void *ret = slab_alloc_node(s, NULL, gfpflags, NUMA_NO_NODE,
					    _RET_IP_, size);

	trace_kmalloc(_RET_IP_, ret, size, s->size, gfpflags, NUMA_NO_NODE);

	ret = kasan_kmalloc(s, ret, size, gfpflags);
	return ret;
}
EXPORT_SYMBOL(kmalloc_trace);

kmem_cache

Slab Memory Allocator는 kmalloc_caches[] 라는 전역 배열을 사용해서 각 크기별 Slab Cache를 관리합니다. 각 Slab Cache는kmem_cache 구조체로 이루어있고, 위의 할당 과정을 보면 해당 구조체가 사용된 것을 확인할 수 있습니다.

1
2
3
kmalloc_trace(
	kmalloc_caches[kmalloc_type(flags, _RET_IP_)][index],
	flags, size);

이렇게 Slab Cache를 통해서 메모리를 효율적으로 관리하는 것을 확인할 수 있습니다.

This post is licensed under CC BY 4.0 by the author.