PAGE_OWNER Feb 13, 2008

이 패치에 원본에 대해서는 다음을 참고하라.

ftp://ftp.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.24-rc5/2.6.24-rc5-mm1/broken-out/page-owner-tracking-leak-detector.patch

이 패치가 하는 역할은 시스템에 커널 메모리 leak을 알 수 있는 간접적인 방법을 제공하는 데 있다.
이 패치를 이번에 arm으로 포팅하였다.

동작메커니즘은 간단하다.

리눅스 커널의 물리 메모리 할당을 위해서는 반드시 alloc_pages함수를 통하게 되어 있다. 그러므로 alloc_pages함수를 통해서 buddy system으로부터 물리 메모리를 할당받는 시점에서 backtrace를 통하여 alloc_pages함수의 호출 경로를 페이지 디스크립터에 기록하여 놓는 것이다.
그런 후 할당된 물리 메모리가 해지될 때 backtrace정보를 삭제하는 것이다. 정확하게는 페이지에 더이상 tracking되지 않고 있다는 표시만 한다.

사용자는 특정 시점에

cat /proc/page_owner > page_owner_full.txt

를 통해서 시스템에 존재하는 할당된 페이지들에 대한 call path를 모두 덤프받게 되며 같이 제공된 application을 통해서 제일 많이 할당된 call path순으로 정렬하여 어떤 함수에서 제일 많이 호출했는지를 알 수 있다.

예를 들어보면 다음과 같다.

> [sorted_page_owner.txt text/plain (100.2KB)]
> 51957 times:
> Page allocated via order 0, mask 0x80d0
> [0xc015b9aa] __alloc_pages+706
> [0xc015b9f0] __get_free_pages+60
> [0xc011b7c9] pgd_alloc+60
> [0xc0122b9e] mm_init+196
> [0xc0122e06] dup_mm+101
> [0xc0122eda] copy_mm+104
> [0xc0123b8c] copy_process+1149
> [0xc0124229] do_fork+141
>
> 12335 times:
> Page allocated via order 0, mask 0x84d0
> [0xc015b9aa] __alloc_pages+706
> [0xc011b6ca] pte_alloc_one+21
> [0xc01632ac] __pte_alloc+21
> [0xc01634bb] copy_pte_range+67
> [0xc0163827] copy_page_range+284
> [0xc0122a79] dup_mmap+427
> [0xc0122e22] dup_mm+129
> [0xc0122eda] copy_mm+104

위의같이 출력된 결과를 검토하면 현재 시스템에 있는 물리 메모리 중 order 0짜리의 페이지가 pgd_alloc을 통하여 51957번 됐음을 알 수 있다. pgd_alloc은 do_fork를 통해서 호출되었다.

그러므로 우리는 현재 시스템에 pgd_alloc과 pair로써 동작하는 메모리 해지 함수가 정상적으로 호출되 되고 있지 않음을 간접적으로 알 수 있게 된다.

arm의 backtrace과정은 간단하다.



(위의 그림에서 sb는 현재 사용되지 않는다.)

위의 그림과 같이 현재의 fp 레지스터는 다음 함수의 frame pointer를 가리키고 있기 때문에 stack이 깨지지 않는 한 그냥 backtrace하여 가면 된다.

하지만 위의 기능이 제대로 동작하기 위해서는 리눅스 커널에 CONFIG_FRAME_POINTER기능이 enable되어 있어야 한다.

0 개의 덧글: