본문 바로가기

Programming

Linux kernel slab allocator

SLAB 은 일반적인 메모리할당 알고리즘의 이름이고 2.6 커널이후부터의 리눅스에서는 SLUB 이라 불린다.

리눅스 커널상의 특정 부분에 task_struct 를 순회하며 각 자료구조의 가상주소를 찍는 코드를 아래처럼 삽입해서 테스트해보니

메모리주소가 모두 task_struct 의 slab item 사이즈의 배수로 되어있다.  즉 SLAB 내에서는 완벽하게 배열처럼 align 이 맞춰져있다.

단지 SLAB 들 자체가 연속할당 되어있지 않을 뿐이다.


아래는 3.8.0 우분투 리눅스 커널에서 돌고있는 task_struct 들의 주소를 찍은것이다. 주소가 전부 0xCD0 의 배수인데 이것은 proc/slabinfo 에 나와있는 task_struct 의 slab 아이템 크기이다. 아래쪽의 3280 이 hex 로 CD0 이다.



테스트에 사용된 LKM 소스코드는 아래와 같다.


#include <linux/module.h>

#include <linux/kernel.h>

#include <linux/sched.h>


#define LOOPCOUNT 100000


int start_module(void)

{

printk("start... loopcount %d\n", LOOPCOUNT);


struct task_struct *task;

struct task_struct *p=current;


for_each_process(p) {

printk("Task %s (%08x)\n",p->comm, p); // task_pid_nr(p)

}


return 0;

}


int exit_module(void)

{

printk("Goodbye\n");

return 0;

}


module_init(start_module);

module_exit(exit_module);


동일한 버전의 바닐라커널상에서도 테스트 하였는데, 모듈을 올리지않고 바닐라 리눅스 커널 자체에 코드를 넣을때는 
특정 시스템콜을 implement 하는 부분을 소스코드상에서 찾고 거기에 내가 원하는 로직을 아래와 같이 넣으면된다.  
여기서는 sys_mkdir 을 이용했다. 먼저 sys_mkdir 의 implementation 을 찾는방법은 아래와 같다.


이런식으로 찾으면 나오지 않고 아래처럼 SYSCALL_DEFINE 매크로를 통해 찾아야 한다.


소스코드상에 아래처럼 코드를 추가했다.


재컴파일해서 mkdir 명령을 내리면 아래처럼 dmesg 에 로그가 찍힌다.